<?php

declare(strict_types=1);

final class DocumentsController
{
    public static function blankAdoption(): void
    {
        $format = ($_GET['format'] ?? 'odt') === 'pdf' ? 'pdf' : 'odt';
        $path = DocumentsService::adoptionTemplate();
        $generated = null;
        if ($format === 'pdf') {
            $dir = sys_get_temp_dir() . '/globinours-doc-' . bin2hex(random_bytes(8));
            mkdir($dir, 0775, true);
            $odt = $dir . '/contrat-adoption-vierge.odt';
            copy($path, $odt);
            $path = DocumentsService::toPdf($odt);
            $generated = $path;
        }
        self::send($path, 'contrat-adoption-vierge.' . $format, $format, $generated);
    }

    public static function blank(): void
    {
        $type = (string) ($_GET['type'] ?? '');
        $names = [
            'adoption' => 'contrat-adoption',
            'abandon' => 'abandon-trouvaille',
            'benevole' => 'contrat-benevole',
            'fa' => 'proposition-fa',
            'pre_adoption' => 'certificat-visite-pre-adoption',
        ];
        if (!isset($names[$type])) {
            http_response_code(404);
            return;
        }
        $format = ($_GET['format'] ?? 'odt') === 'pdf' ? 'pdf' : 'odt';
        $source = DocumentsService::template($type);
        $dir = sys_get_temp_dir() . '/globinours-doc-' . bin2hex(random_bytes(8));
        mkdir($dir, 0775, true);
        $odt = $dir . '/' . $names[$type] . '-vierge.odt';
        copy($source, $odt);
        $path = $format === 'pdf' ? DocumentsService::toPdf($odt) : $odt;
        self::send($path, $names[$type] . '-vierge.' . $format, $format, $path);
    }

    public static function adoption(): void
    {
        $id = (int) ($_GET['animal_id'] ?? 0);
        if ($id <= 0) {
            http_response_code(400);
            return;
        }
        $db = DB::pdo();
        $stmt = $db->prepare('SELECT * FROM animals WHERE id=:id AND deleted_at IS NULL');
        $stmt->execute([':id' => $id]);
        $animal = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!$animal) {
            http_response_code(404);
            return;
        }
        $stmt = $db->prepare('SELECT * FROM adoptions WHERE animal_id=:id ORDER BY id DESC LIMIT 1');
        $stmt->execute([':id' => $id]);
        $adoption = $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
        $stmt = $db->prepare(
            'SELECT done_date,due_date FROM vaccinations WHERE animal_id=:id ORDER BY done_date DESC,id DESC LIMIT 1',
        );
        $stmt->execute([':id' => $id]);
        $vaccine = $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
        $format = ($_GET['format'] ?? 'pdf') === 'odt' ? 'odt' : 'pdf';
        $odt = DocumentsService::generateAdoption($animal, $adoption, $vaccine);
        $path = $format === 'pdf' ? DocumentsService::toPdf($odt) : $odt;
        self::send(
            $path,
            'contrat-adoption-' . self::safeName((string) $animal['name']) . '.' . $format,
            $format,
            $path,
        );
    }

    public static function abandon(): void
    {
        $id = (int) ($_GET['animal_id'] ?? 0);
        $db = DB::pdo();
        $stmt = $db->prepare('SELECT * FROM animals WHERE id=:id AND deleted_at IS NULL');
        $stmt->execute([':id' => $id]);
        $animal = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!$animal) {
            http_response_code(404);
            return;
        }
        $format = ($_GET['format'] ?? 'pdf') === 'odt' ? 'odt' : 'pdf';
        $odt = DocumentsService::generateAbandon($animal);
        $path = $format === 'pdf' ? DocumentsService::toPdf($odt) : $odt;
        self::send(
            $path,
            'abandon-trouvaille-' . self::safeName((string) $animal['name']) . '.' . $format,
            $format,
            $path,
        );
    }

    public static function contact(): void
    {
        $id = (int) ($_GET['contact_id'] ?? 0);
        $type = (string) ($_GET['type'] ?? '');
        $role = $type === 'benevole' ? 'benevole' : ($type === 'fa' ? 'fa' : null);
        if (!$role) {
            http_response_code(400);
            return;
        }
        $db = DB::pdo();
        $stmt = $db->prepare(
            'SELECT dc.* FROM directory_contacts dc JOIN directory_contact_roles r ON r.contact_id=dc.id AND r.role=:role WHERE dc.id=:id AND dc.deleted_at IS NULL',
        );
        $stmt->execute([':role' => $role, ':id' => $id]);
        $contact = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!$contact) {
            http_response_code(404);
            return;
        }
        $format = ($_GET['format'] ?? 'pdf') === 'odt' ? 'odt' : 'pdf';
        $odt = DocumentsService::generateContact($type, $contact);
        $path = $format === 'pdf' ? DocumentsService::toPdf($odt) : $odt;
        self::send($path, $type . '-' . self::safeName((string) $contact['name']) . '.' . $format, $format, $path);
    }

    private static function send(string $path, string $filename, string $format, ?string $cleanup): void
    {
        if (!is_file($path)) {
            http_response_code(500);
            return;
        }
        header('Content-Type: ' . ($format === 'pdf' ? 'application/pdf' : 'application/vnd.oasis.opendocument.text'));
        header('Content-Length: ' . filesize($path));
        header(
            'Content-Disposition: ' . ($format === 'pdf' ? 'inline' : 'attachment') . '; filename="' . $filename . '"',
        );
        readfile($path);
        if ($cleanup) {
            DocumentsService::cleanup($cleanup);
        }
        exit();
    }
    private static function safeName(string $name): string
    {
        $name = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $name) ?: 'chat';
        return strtolower(trim(preg_replace('/[^a-zA-Z0-9]+/', '-', $name), '-')) ?: 'chat';
    }
}
