<?php

namespace App\Services\Admin;

use App\Models\AdminUser;
use App\Models\ReportJob;
use App\Services\AuditLogger;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

/**
 * 报表导出任务：落库 `report_jobs`（同步生成，可后续接队列）。
 */
final class AdminReportJobService
{
    public function __construct(
        private readonly AdminReportQueryService $queryService,
    ) {}

    /**
     * @param  array<string, mixed>|null  $filterJson
     */
    public function enqueue(AdminUser $admin, Request $request, string $reportType, string $exportFormat, ?array $filterJson): ReportJob
    {
        return DB::transaction(function () use ($admin, $request, $reportType, $exportFormat, $filterJson): ReportJob {
            $params = $this->extractReportParameters($request, $filterJson);
            $range = $this->queryService->resolveDateRange($params);
            $dateFrom = $range['date_from'];
            $dateTo = $range['date_to'];

            $jobNo = 'RPT'.now()->format('YmdHis').strtoupper(Str::random(4));
            $exportFormat = $exportFormat === 'xlsx' ? 'xlsx' : 'csv';

            $pathSuffix = $this->queryService->resolveOutputPathSuffix($reportType, $params, $dateFrom, $dateTo);

            $job = ReportJob::query()->create([
                'job_no' => $jobNo,
                'admin_user_id' => (int) $admin->getKey(),
                'report_type' => $reportType,
                'export_format' => $exportFormat,
                'filter_json' => $params,
                'status' => 'completed',
                'output_path' => 'reports/'.$this->queryService->reportLabel($reportType).'_'.$pathSuffix.'.'.$exportFormat,
                'error_message' => null,
                'finished_at' => now(),
            ]);

            AuditLogger::recordForAdmin(
                $admin,
                $request,
                'report_jobs',
                'enqueue',
                'report_job',
                (string) $job->getKey(),
                null,
                [
                    'job_no' => $jobNo,
                    'report_type' => $reportType,
                    'export_format' => $exportFormat,
                ],
            );

            return $job;
        });
    }

    /**
     * @return list<array<int, string|int|float|null>>
     */
    public function reportRows(string $reportType, ?array $filterJson, ?AdminUser $scopedAdmin = null): array
    {
        return $this->queryService->reportRows($reportType, $filterJson, $scopedAdmin);
    }

    public function reportLabel(string $reportType): string
    {
        return $this->queryService->reportLabel($reportType);
    }

    /**
     * @return array<string, mixed>
     */
    private function extractReportParameters(Request $request, ?array $filterJson): array
    {
        $parameters = $request->input('parameters');
        if (is_array($parameters)) {
            return $parameters;
        }

        if (is_array($filterJson)) {
            return $filterJson;
        }

        return [];
    }
}
