<?php

declare(strict_types=1);

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\GenerateReportRequest;
use App\Services\Reports\FinancialReportService;
use App\Services\Reports\ReportExportService;
use Illuminate\Support\Carbon;
use Inertia\Inertia;
use Inertia\Response;
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;

class ReportController extends Controller
{
    public function __construct(
        private FinancialReportService $reportService,
        private ReportExportService $exportService,
    ) {}

    public function index(): Response
    {
        return Inertia::render('Admin/Reports/Index');
    }

    public function generate(GenerateReportRequest $request): Response
    {
        $reportType = $request->validated('report_type');
        $startDate = $request->validated('start_date') ? Carbon::parse($request->validated('start_date')) : null;
        $endDate = $request->validated('end_date') ? Carbon::parse($request->validated('end_date')) : null;
        $serviceType = $request->validated('service_type');

        $data = $this->generateReportData($reportType, $startDate, $endDate, $serviceType);

        $meta = $this->buildMeta($reportType, $startDate, $endDate, $serviceType);

        return Inertia::render('Admin/Reports/Show', [
            'reportType' => $reportType,
            'reportData' => $data,
            'reportMeta' => $meta,
        ]);
    }

    public function export(GenerateReportRequest $request): SymfonyResponse
    {
        $reportType = $request->validated('report_type');
        $format = $request->validated('format', 'pdf');
        $startDate = $request->validated('start_date') ? Carbon::parse($request->validated('start_date')) : null;
        $endDate = $request->validated('end_date') ? Carbon::parse($request->validated('end_date')) : null;
        $serviceType = $request->validated('service_type');

        $data = $this->generateReportData($reportType, $startDate, $endDate, $serviceType);
        $meta = $this->buildMeta($reportType, $startDate, $endDate, $serviceType);

        return match ($format) {
            'csv' => $this->exportService->toCsv($reportType, $data, $meta),
            'json' => $this->exportService->toJson($reportType, $data, $meta),
            default => $this->exportService->toPdf($reportType, $data, $meta),
        };
    }

    /**
     * Generate report data based on type.
     *
     * @return array<string, mixed>
     */
    private function generateReportData(string $reportType, ?Carbon $startDate, ?Carbon $endDate, ?string $serviceType): array
    {
        return match ($reportType) {
            'revenue' => $this->reportService->revenueReport($startDate, $endDate, $serviceType),
            'profit_loss' => $this->reportService->profitLossReport($startDate, $endDate),
            'tax' => $this->reportService->taxReport($startDate, $endDate),
            'aging' => $this->reportService->agingReport(),
            'refund' => $this->reportService->refundReport($startDate, $endDate),
            'subscription' => $this->reportService->subscriptionReport($startDate, $endDate),
            default => [],
        };
    }

    /**
     * Build report metadata.
     *
     * @return array{title: string, start_date: string|null, end_date: string|null, generated_at: string, service_type: string|null}
     */
    private function buildMeta(string $reportType, ?Carbon $startDate, ?Carbon $endDate, ?string $serviceType): array
    {
        $titles = [
            'revenue' => 'Revenue Report',
            'profit_loss' => 'Profit & Loss Report',
            'tax' => 'Tax Report',
            'aging' => 'Aging Report',
            'refund' => 'Refund Report',
            'subscription' => 'Subscription Report',
        ];

        return [
            'title' => $titles[$reportType] ?? 'Report',
            'start_date' => $startDate?->toDateString(),
            'end_date' => $endDate?->toDateString(),
            'generated_at' => now()->toIso8601String(),
            'service_type' => $serviceType,
        ];
    }
}
