<?php

declare(strict_types=1);

namespace App\Http\Controllers\Api\Certificates;

use App\Http\Controllers\Api\Core\BaseApiController;
use App\Services\Certificates\CertificateAdminService;
use App\Services\Certificates\CertificatePdfService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Log;

class CertificateController extends BaseApiController
{
    public function __construct(
        private CertificateAdminService $service,
        private CertificatePdfService $pdfService,
    ) {
        parent::__construct();
    }

    public function dashboard(Request $request): JsonResponse
    {
        try {
            return response()->json([
                'ok' => true,
                'data' => $this->service->dashboard($request->query('school_year')),
            ]);
        } catch (\Throwable $e) {
            Log::error('Certificate dashboard failed', ['exception' => $e]);

            return $this->error('Failed to load certificate dashboard.', 500);
        }
    }

    public function formOptions(Request $request): JsonResponse
    {
        return $this->dashboard($request);
    }

    public function auditLog(Request $request): JsonResponse
    {
        try {
            return response()->json([
                'ok' => true,
                'data' => $this->service->auditLog($request->query('school_year')),
            ]);
        } catch (\Throwable $e) {
            Log::error('Certificate audit log failed', ['exception' => $e]);

            return $this->error('Failed to load certificate audit log.', 500);
        }
    }

    public function generate(Request $request): Response|JsonResponse
    {
        $studentIds = $request->input('student_ids', []);
        $certDate = trim((string) ($request->input('cert_date') ?? date('m/d/Y')));
        $classSectionId = $request->input('class_section_id');
        $schoolYear = $request->input('school_year');

        try {
            $payload = $this->service->issueCertificates(
                is_array($studentIds) ? $studentIds : [],
                $certDate,
                $classSectionId !== null && $classSectionId !== '' ? (int) $classSectionId : null,
                is_string($schoolYear) ? $schoolYear : null,
                $this->getCurrentUserId()
            );
            $pdfContent = $this->pdfService->generate(
                $payload['students'],
                $payload['cert_date_display']
            );
        } catch (\InvalidArgumentException $e) {
            return $this->error($e->getMessage(), 422);
        } catch (\RuntimeException $e) {
            return $this->error($e->getMessage(), 422);
        } catch (\Throwable $e) {
            Log::error('Certificate generation failed', ['exception' => $e]);

            return $this->error('Failed to generate certificates.', 500);
        }

        $filename = 'Certificates_'.date('Ymd_His').'.pdf';

        return response($pdfContent, 200, [
            'Content-Type' => 'application/pdf',
            'Content-Disposition' => 'inline; filename="'.$filename.'"',
        ]);
    }

    public function reprint(string $certificateNumber): Response|JsonResponse
    {
        try {
            $payload = $this->service->reprintPayload($certificateNumber);
            if ($payload === null) {
                return $this->error('Certificate not found: '.$certificateNumber, 404);
            }

            $pdfContent = $this->pdfService->generate(
                [$payload['student']],
                $payload['cert_date_display']
            );
        } catch (\Throwable $e) {
            Log::error('Certificate reprint failed', [
                'certificate_number' => $certificateNumber,
                'exception' => $e,
            ]);

            return $this->error('Failed to reprint certificate.', 500);
        }

        $filename = 'Certificate_'.strtoupper($certificateNumber).'.pdf';

        return response($pdfContent, 200, [
            'Content-Type' => 'application/pdf',
            'Content-Disposition' => 'inline; filename="'.$filename.'"',
        ]);
    }

    public function verify(string $token): JsonResponse
    {
        try {
            $payload = $this->service->verifyPayload($token);
        } catch (\Throwable $e) {
            Log::error('Certificate verify failed', ['token' => $token, 'exception' => $e]);

            return $this->error('Failed to verify certificate.', 500);
        }

        if ($payload === null) {
            return response()->json([
                'ok' => false,
                'message' => 'Certificate not found.',
            ], 404);
        }

        return response()->json([
            'ok' => true,
            'data' => $payload,
        ]);
    }
}
