<?php

declare(strict_types=1);

namespace App\Services\Reports;

use App\Models\ReportJob;
use App\Services\Reports\Formatters\CsvFormatter;
use App\Services\Reports\Formatters\JsonFormatter;
use App\Services\Reports\Formatters\PdfStubFormatter;
use App\Services\Reports\Formatters\ReportFormatter;
use App\Services\Reports\Formatters\XlsxFormatter;
use App\Services\Reports\Providers\BillingSummaryProvider;
use App\Services\Reports\Providers\DealsExportProvider;
use App\Services\Reports\Providers\ManagersSummaryProvider;
use App\Services\Reports\Providers\ReportDataProvider;
use App\Services\Reports\Providers\SourcesSummaryProvider;
use InvalidArgumentException;

/**
 * Резолвит ReportDataProvider по `type` и ReportFormatter по `format`.
 *
 * 4 provider'а (deals_export, managers_summary, sources_summary,
 * billing_summary) × 4 formatter'а (csv, xlsx, json, pdf). PDF на MVP —
 * stub: PdfStubFormatter кидает RuntimeException → GenerateReportJob
 * ловит → failed-job (intended, Post-MVP).
 */
class ReportGeneratorRegistry
{
    public function __construct(
        private readonly DealsExportProvider $dealsExport,
        private readonly ManagersSummaryProvider $managersSummary,
        private readonly SourcesSummaryProvider $sourcesSummary,
        private readonly BillingSummaryProvider $billingSummary,
        private readonly CsvFormatter $csv,
        private readonly XlsxFormatter $xlsx,
        private readonly JsonFormatter $json,
        private readonly PdfStubFormatter $pdf,
    ) {}

    public function provider(string $type): ReportDataProvider
    {
        return match ($type) {
            'deals_export' => $this->dealsExport,
            'managers_summary' => $this->managersSummary,
            'sources_summary' => $this->sourcesSummary,
            'billing_summary' => $this->billingSummary,
            default => throw new InvalidArgumentException("Тип отчёта не реализован: {$type}"),
        };
    }

    public function formatter(string $format): ReportFormatter
    {
        return match ($format) {
            'csv' => $this->csv,
            'xlsx' => $this->xlsx,
            'json' => $this->json,
            'pdf' => $this->pdf,
            default => throw new InvalidArgumentException("Формат не поддерживается: {$format}"),
        };
    }

    public function isSupported(string $type, string $format): bool
    {
        // Все 4 типа ReportJob::TYPES реализованы (F1, 2026-05-16).
        // PDF валидируется, но PdfStubFormatter кидает RuntimeException →
        // GenerateReportJob ловит → failed-job (intended, Post-MVP).
        return in_array($type, ReportJob::TYPES, true)
            && in_array($format, ReportJob::FORMATS, true);
    }
}
