<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Services\CertificateService;
use Dompdf\Dompdf;

class CertificateController extends Controller
{
    private CertificateService $certificates;

    public function __construct()
    {
        $this->certificates = new CertificateService();
    }

    public function studentCertificates(): string
    {
        require_role('student');

        return $this->view('certificates/student', [
            'title' => 'Meus certificados',
            'certificates' => $this->certificates->certificatesForStudent((int) current_user()['id']),
        ]);
    }

    public function issue(Request $request): void
    {
        require_role('student');

        if (!verify_csrf((string) $request->post('_csrf_token', ''))) {
            flash('error', 'Sessao expirada. Tente novamente.');
            app()->response()->back();
        }

        $result = $this->certificates->issueForEnrollment((int) $request->post('enrollment_id'), current_user());

        if (!$result['ok']) {
            flash('error', $result['error']);
            app()->response()->back();
        }

        flash('success', 'Certificado emitido com sucesso.');
        app()->response()->redirect('/certificates/show?id=' . $result['certificate']['id']);
    }

    public function show(Request $request): string
    {
        require_auth();
        $certificate = $this->certificates->find((int) $request->input('id'));

        if (!$certificate || !$this->certificates->canUserSee($certificate, current_user())) {
            flash('error', 'Certificado nao encontrado.');
            app()->response()->redirect('/dashboard');
        }

        return $this->view('certificates/show', [
            'title' => 'Certificado ' . $certificate['certificate_number'],
            'certificate' => $certificate,
            'validationUrl' => $this->validationUrl($certificate),
        ]);
    }

    public function pdf(Request $request): void
    {
        require_auth();
        $certificate = $this->certificates->find((int) $request->input('id'));

        if (!$certificate || !$this->certificates->canUserSee($certificate, current_user())) {
            flash('error', 'Certificado nao encontrado.');
            app()->response()->redirect('/dashboard');
        }

        $dompdf = new Dompdf();
        $dompdf->loadHtml($this->pdfHtml($certificate));
        $dompdf->setPaper('A4', 'landscape');
        $dompdf->render();
        $dompdf->stream($certificate['certificate_number'] . '.pdf', ['Attachment' => true]);
        exit;
    }

    public function validate(Request $request): string
    {
        $code = (string) $request->input('code', '');
        $certificate = $code !== '' ? $this->certificates->findByCode($code) : null;

        return $this->view('certificates/validate', [
            'title' => 'Validar certificado',
            'code' => $code,
            'certificate' => $certificate,
        ]);
    }

    public function adminCertificates(Request $request): string
    {
        require_role('admin');
        $filters = ['search' => (string) $request->input('search', '')];

        return $this->view('admin/certificates/index', [
            'title' => 'Certificados',
            'certificates' => $this->certificates->all($filters),
            'filters' => $filters,
        ]);
    }

    public function reissue(Request $request): void
    {
        require_role('admin');

        if (!verify_csrf((string) $request->post('_csrf_token', ''))) {
            flash('error', 'Sessao expirada. Tente novamente.');
            app()->response()->back();
        }

        $result = $this->certificates->reissue((int) $request->post('id'), (int) current_user()['id']);
        flash($result['ok'] ? 'success' : 'error', $result['ok'] ? 'Certificado reemitido.' : $result['error']);
        app()->response()->back();
    }

    private function validationUrl(array $certificate): string
    {
        $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
        $host = $_SERVER['HTTP_HOST'] ?? '127.0.0.1:8000';

        return $scheme . '://' . $host . '/certificates/validate?code=' . urlencode((string) $certificate['validation_code']);
    }

    private function pdfHtml(array $certificate): string
    {
        $validationUrl = $this->validationUrl($certificate);

        return '<!doctype html><html><head><meta charset="utf-8"><style>
            body{font-family:DejaVu Sans,Arial,sans-serif;color:#17202a;background:#f7faf9;margin:0;padding:36px}
            .certificate{height:620px;border:8px solid #0f766e;background:#fff;padding:46px;text-align:center}
            .eyebrow{color:#0f766e;font-weight:700;text-transform:uppercase;letter-spacing:1px}
            h1{font-size:48px;margin:22px 0 10px}
            h2{font-size:34px;margin:18px 0;color:#0f766e}
            p{font-size:18px;line-height:1.5}
            .meta{margin-top:32px;display:table;width:100%;font-size:14px}
            .cell{display:table-cell;width:33%;text-align:center}
            .code{margin-top:28px;padding:14px;border:1px solid #dfe6e9;font-size:14px}
        </style></head><body><section class="certificate">
            <div class="eyebrow">Certificado de conclusao</div>
            <h1>' . e((string) $certificate['student_name']) . '</h1>
            <p>concluiu com sucesso o curso</p>
            <h2>' . e((string) $certificate['course_title']) . '</h2>
            <p>Emitido por ' . e((string) $certificate['issuer_name']) . ' em ' . e(format_date((string) $certificate['issued_at'])) . '.</p>
            <div class="meta">
                <div class="cell"><strong>Carga horaria</strong><br>' . e((string) $certificate['workload_hours']) . ' horas</div>
                <div class="cell"><strong>Conclusao</strong><br>' . e((string) $certificate['completion_percentage']) . '%</div>
                <div class="cell"><strong>Numero</strong><br>' . e((string) $certificate['certificate_number']) . '</div>
            </div>
            <div class="code">Codigo de validacao: <strong>' . e((string) $certificate['validation_code']) . '</strong><br>' . e($validationUrl) . '</div>
        </section></body></html>';
    }
}
