<?php

namespace Ignite\Core\Traits;

use Ignite\Core\Models\Grid\AbstractTable;
use Ignite\Core\Services\Reports\ReportDownloadRequest;
use Ignite\Core\Services\Reports\ReportDownloadService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

trait QueuesReportDownloads
{
    /**
     * Queue large DataTables CSV exports and let smaller exports fall through.
     *
     * Returning null tells the controller to keep using the existing Yajra inline
     * export path. Returning JSON tells the page-specific button that a background
     * report download was created.
     *
     * @param Request $request
     * @param string $routeName
     * @param class-string<AbstractTable> $tableClass
     * @param string $downloadName
     * @param array<string, mixed> $params
     * @param array<string, mixed> $filters
     * @return JsonResponse|null
     */
    protected function queuedDataTableCsvExportResponse(
        Request $request,
        string $routeName,
        string $tableClass,
        string $downloadName,
        array $params = [],
        array $filters = []
    ): ?JsonResponse {
        if (! $this->isDataTableCsvExportRequest($request, $routeName)) {
            return null;
        }

        $downloadRequest = ReportDownloadRequest::fromHttpRequest(
            $request,
            auth()->id(),
            $tableClass,
            $downloadName,
            ReportDownloadRequest::FORMAT_CSV,
            $params,
            $filters
        );

        /** @var ReportDownloadService $downloadService */
        $downloadService = app(ReportDownloadService::class);
        if (! $downloadService->shouldQueue($downloadRequest)) {
            return null;
        }

        $download = $downloadService->requestReportDownload($downloadRequest);

        return response()->json([
            'queued' => true,
            'download_id' => $download->getKey(),
            'status' => 'info',
            'message' => sprintf(
                'Your %s CSV export is being prepared. Please check back for the download shortly.',
                $downloadName
            ),
        ], 202);
    }

    /**
     * Determine whether this request is a CSV export for the expected route.
     *
     * @param Request $request
     * @param string $routeName
     * @return bool
     */
    protected function isDataTableCsvExportRequest(Request $request, string $routeName): bool
    {
        return $request->isMethod('post')
            && $request->input('action') === ReportDownloadRequest::FORMAT_CSV
            && optional($request->route())->getName() === $routeName;
    }
}
