<?php

namespace App\Http\Controllers\Api\V1\Admin\Reports;

use App\Models\AdminUser;
use App\Models\ReportJob;
use App\Services\Admin\AdminReportJobService;
use App\Services\Admin\AdminReportQueryService;
use App\Services\Admin\AdminReportSpreadsheetExporter;
use Symfony\Component\HttpFoundation\StreamedResponse;

/** GET /api/v1/admin/report-jobs/{report_job}/download */
final class ReportJobDownloadController
{
    public function __invoke(
        ReportJob $report_job,
        AdminReportJobService $service,
        AdminReportQueryService $queryService,
        AdminReportSpreadsheetExporter $spreadsheetExporter,
    ): StreamedResponse {
        $filterJson = is_array($report_job->filter_json) ? $report_job->filter_json : null;
        $range = $queryService->resolveDateRange($filterJson);
        $dateFrom = $range['date_from'];
        $dateTo = $range['date_to'];
        $label = $service->reportLabel((string) $report_job->report_type);
        $pathSuffix = $queryService->resolveOutputPathSuffix(
            (string) $report_job->report_type,
            $filterJson,
            $dateFrom,
            $dateTo,
        );
        $filename = $label.'_'.$pathSuffix.'.'.$report_job->export_format;
        $scopedAdmin = AdminUser::query()->find((int) $report_job->admin_user_id);
        $rows = $service->reportRows((string) $report_job->report_type, $filterJson, $scopedAdmin);

        if ((string) $report_job->export_format === 'xlsx') {
            return $spreadsheetExporter->streamDownload($rows, $filename);
        }

        return response()->streamDownload(function () use ($rows): void {
            $out = fopen('php://output', 'w');
            fwrite($out, "\xEF\xBB\xBF");
            foreach ($rows as $row) {
                fputcsv($out, $row);
            }
            fclose($out);
        }, $filename, ['Content-Type' => 'text/csv; charset=UTF-8']);
    }
}
