<?php

namespace App\Controllers\Api\V1;

use App\Controllers\BaseController;
use App\Services\Reporting\AdminReportingService;
use App\Services\Reporting\ReportExportService;

class AdminReportController extends BaseController
{
    private function reporting(): AdminReportingService
    {
        // Constructed per-request (not in initController) since it throws
        // ForbiddenException in its constructor for non-super-admins —
        // that needs to surface as a normal 403 JSON response, not a
        // fatal error during controller setup.
        return new AdminReportingService();
    }

    /**
     * "Which agency hired whom" — per-agency hire counts with a drill-down
     * list of each hire (candidate, job, hired date).
     */
    public function hiresByAgency()
    {
        return $this->jsonSuccess($this->reporting()->hiresByAgency());
    }

    /**
     * Per-candidate application history — how many applications, and for
     * each one, which company (if any) hired them and when.
     */
    public function candidateApplications(int $candidateUserId)
    {
        return $this->jsonSuccess($this->reporting()->candidateApplicationReport($candidateUserId));
    }

    public function revenue()
    {
        [$from, $to] = $this->dateRange();
        try {
            $data = $this->reporting()->revenue($from, $to);
        } catch (\App\Exceptions\ForbiddenException $e) {
            return $this->jsonError([['code' => 'FORBIDDEN', 'message' => $e->getMessage()]], 403);
        }
        return $this->maybeExport($data, 'revenue-report', 'Revenue Report');
    }

    public function subscriptions()
    {
        try {
            $data = $this->reporting()->subscriptions();
        } catch (\App\Exceptions\ForbiddenException $e) {
            return $this->jsonError([['code' => 'FORBIDDEN', 'message' => $e->getMessage()]], 403);
        }
        return $this->jsonSuccess($data);
    }

    public function agencies()
    {
        try {
            $data = $this->reporting()->agencies();
        } catch (\App\Exceptions\ForbiddenException $e) {
            return $this->jsonError([['code' => 'FORBIDDEN', 'message' => $e->getMessage()]], 403);
        }
        return $this->jsonSuccess($data);
    }

    public function recruiters()
    {
        try {
            $data = $this->reporting()->recruiters();
        } catch (\App\Exceptions\ForbiddenException $e) {
            return $this->jsonError([['code' => 'FORBIDDEN', 'message' => $e->getMessage()]], 403);
        }
        return $this->jsonSuccess($data);
    }

    public function candidates()
    {
        try {
            $data = $this->reporting()->candidates();
        } catch (\App\Exceptions\ForbiddenException $e) {
            return $this->jsonError([['code' => 'FORBIDDEN', 'message' => $e->getMessage()]], 403);
        }
        return $this->jsonSuccess($data);
    }

    public function jobs()
    {
        try {
            $data = $this->reporting()->jobs();
        } catch (\App\Exceptions\ForbiddenException $e) {
            return $this->jsonError([['code' => 'FORBIDDEN', 'message' => $e->getMessage()]], 403);
        }
        return $this->jsonSuccess($data);
    }

    public function applications()
    {
        try {
            $data = $this->reporting()->applications();
        } catch (\App\Exceptions\ForbiddenException $e) {
            return $this->jsonError([['code' => 'FORBIDDEN', 'message' => $e->getMessage()]], 403);
        }
        return $this->jsonSuccess($data);
    }

    public function credits()
    {
        try {
            $data = $this->reporting()->credits();
        } catch (\App\Exceptions\ForbiddenException $e) {
            return $this->jsonError([['code' => 'FORBIDDEN', 'message' => $e->getMessage()]], 403);
        }
        return $this->jsonSuccess($data);
    }

    public function wallet()
    {
        try {
            $data = $this->reporting()->wallet();
        } catch (\App\Exceptions\ForbiddenException $e) {
            return $this->jsonError([['code' => 'FORBIDDEN', 'message' => $e->getMessage()]], 403);
        }
        return $this->jsonSuccess($data);
    }

    public function payments()
    {
        [$from, $to] = $this->dateRange();
        try {
            $data = $this->reporting()->payments($from, $to);
        } catch (\App\Exceptions\ForbiddenException $e) {
            return $this->jsonError([['code' => 'FORBIDDEN', 'message' => $e->getMessage()]], 403);
        }
        return $this->jsonSuccess($data);
    }

    private function dateRange(): array
    {
        $from = $this->request->getGet('from') ?? date('Y-m-d', strtotime('-30 days'));
        $to = $this->request->getGet('to') ?? date('Y-m-d');
        return [$from, $to];
    }

    /**
     * Shared export handling: ?export=pdf|excel|csv on any report endpoint
     * triggers a file download instead of the normal JSON response.
     */
    private function maybeExport(array $data, string $filenameBase, string $title)
    {
        $format = $this->request->getGet('export');
        if (! $format) {
            return $this->jsonSuccess($data);
        }

        $exporter = new ReportExportService();
        try {
            $path = match ($format) {
                'pdf'   => $exporter->toPdf($data, $filenameBase, $title),
                'excel' => $exporter->toExcel($data, $filenameBase, $title),
                'csv'   => $exporter->toCsv($data, $filenameBase),
                default => null,
            };
        } catch (\RuntimeException $e) {
            return $this->jsonError([['code' => 'EXPORT_UNAVAILABLE', 'message' => $e->getMessage()]], 501);
        }

        if (! $path) {
            return $this->jsonError([['code' => 'INVALID_EXPORT_FORMAT', 'message' => 'export must be pdf, excel, or csv.']], 400);
        }

        return $this->response->download($path, null);
    }
}
