<?php
declare(strict_types=1);
require_once __DIR__ . "/../config/database.php";
require_once __DIR__ . "/../includes/auth.php";
require_once __DIR__ . "/../includes/helpers.php";
require_once __DIR__ . "/../includes/attestation_qr.php";
require_once __DIR__ . "/../includes/qr_autoload.php";
requireAuth();
if (!hasRole(["admin", "secretaire"])) {
    header("Location: /PIS/attestations/list.php");
    exit;
}
header("Content-Type: text/html; charset=UTF-8");

$mode = $_GET["mode"] ?? "all";
$formationId = (int) ($_GET["formation_id"] ?? 0);
$stagiaireId = (int) ($_GET["stagiaire_id"] ?? 0);
$signataire = trim($_GET["signataire"] ?? "");
$dateDebut = trim($_GET["date_debut"] ?? "");
$dateFin = trim($_GET["date_fin"] ?? "");
$storageRoot = __DIR__ . "/produced";
$productionDate = date("Y-m-d");

$whereClauses = [];
$params = [];
if ($mode === "module" && $formationId > 0) {
    $whereClauses[] = "f.id = :formation_id";
    $params["formation_id"] = $formationId;
}
if ($mode === "person" && $stagiaireId > 0) {
    $whereClauses[] = "s.id = :stagiaire_id";
    $params["stagiaire_id"] = $stagiaireId;
    if ($formationId > 0) {
        $whereClauses[] = "f.id = :formation_id";
        $params["formation_id"] = $formationId;
    }
}
if ($mode === "date" && $dateDebut !== "") {
    if ($formationId > 0) {
        $whereClauses[] = "f.id = :formation_id";
        $params["formation_id"] = $formationId;
    }
    $whereClauses[] = "i.date_inscription >= :date_debut";
    $params["date_debut"] = $dateDebut;
    if ($dateFin !== "") {
        $whereClauses[] = "i.date_inscription <= :date_fin";
        $params["date_fin"] = $dateFin;
    }
}

$where = $whereClauses !== [] ? " WHERE " . implode(" AND ", $whereClauses) : "";

$sql = "SELECT s.nom, s.prenoms, CONCAT(s.nom, ' ', s.prenoms) AS apprenant, s.sexe, s.date_naissance, s.lieu_naissance, f.titre AS formation, f.date_debut, f.date_fin, i.date_inscription
        FROM inscriptions i
        JOIN stagiaires s ON i.stagiaire_id = s.id
        JOIN formations f ON i.formation_id = f.id
        {$where}
        ORDER BY s.nom, s.prenoms";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$rows = $stmt->fetchAll();
$today = date("d/m/Y");
$isEmpty = count($rows) === 0;
$signataire = trim($signataire) !== "" ? $signataire : " ";

$logoPath = "";
$logoCandidates = [
    __DIR__ . "/../assets/images/logo-uk-extended0-5x.png",
    __DIR__ . "/../assets/images/logo-uk-extended0-5x.jpg",
    __DIR__ . "/../assets/images/logo-uk-extended0-5x.jpeg",
    __DIR__ . "/../assets/images/logo-uk-extended0-5x.webp",
];
foreach ($logoCandidates as $candidate) {
    if (file_exists($candidate)) {
        $logoPath = str_replace(__DIR__ . "/..", "/PIS", $candidate);
        break;
    }
}

$watermarkPath = "";
$watermarkCandidates = [
    __DIR__ . "/../assets/images/Universite-de-Kara-togo.png",
    __DIR__ . "/../assets/images/Universite-de-Kara-togo.jpg",
    __DIR__ . "/../assets/images/Universite-de-Kara-togo.jpeg",
    __DIR__ . "/../assets/images/Universite-de-Kara-togo.webp",
];
foreach ($watermarkCandidates as $candidate) {
    if (file_exists($candidate)) {
        $watermarkPath = str_replace(__DIR__ . "/..", "/PIS", $candidate);
        break;
    }
}
if ($watermarkPath === "") {
    $watermarkPath = $logoPath;
}

function formatAttestationData(array $row, int $idx, string $today): array
{
    $numero = sprintf("PIS-%s-%04d", date("Y"), $idx + 1);
    $isFemme = strtoupper((string) ($row["sexe"] ?? "")) === "F";
    $civilite = $isFemme ? "Madame" : "Monsieur";
    $neText = "né(e)";
    $dateNaissance = (string) ($row["date_naissance"] ?? "");
    if ($dateNaissance !== "") {
        $tmpDate = DateTime::createFromFormat("Y-m-d", $dateNaissance);
        if ($tmpDate instanceof DateTime) {
            $dateNaissance = $tmpDate->format("d-m-Y");
        }
    }

    $dateDebut = (string) ($row["date_debut"] ?? "");
    $dateFin = (string) ($row["date_fin"] ?? "");
    $periode = "";
    if ($dateDebut !== "" && $dateFin !== "") {
        $d = DateTime::createFromFormat("Y-m-d", $dateDebut);
        $f = DateTime::createFromFormat("Y-m-d", $dateFin);
        if ($d instanceof DateTime && $f instanceof DateTime) {
            $jourD = $d->format("d");
            $jourF = $f->format("d");
            $moisD = $d->format("F");
            $moisF = $f->format("F");
            $anneeD = $d->format("Y");
            $anneeF = $f->format("Y");
            
            // Traduire les mois en français
            $moisFr = [
                "January" => "janvier", "February" => "février", "March" => "mars",
                "April" => "avril", "May" => "mai", "June" => "juin",
                "July" => "juillet", "August" => "août", "September" => "septembre",
                "October" => "octobre", "November" => "novembre", "December" => "décembre"
            ];
            $moisD = $moisFr[$moisD] ?? $moisD;
            $moisF = $moisFr[$moisF] ?? $moisF;
            
            if ($anneeD === $anneeF && $moisD === $moisF) {
                // Même mois et même année: "04 au 16 mai 2026"
                $periode = "{$jourD} au {$jourF} {$moisD} {$anneeD}";
            } elseif ($anneeD === $anneeF) {
                // Même année, mois différents: "04 mai au 16 juin 2026"
                $periode = "{$jourD} {$moisD} au {$jourF} {$moisF} {$anneeD}";
            } else {
                // Années différentes: "04 mai 2026 au 16 juin 2027"
                $periode = "{$jourD} {$moisD} {$anneeD} au {$jourF} {$moisF} {$anneeF}";
            }
        }
    } elseif ($dateDebut !== "") {
        $d = DateTime::createFromFormat("Y-m-d", $dateDebut);
        if ($d instanceof DateTime) {
            $jour = $d->format("d");
            $mois = $d->format("F");
            $annee = $d->format("Y");
            $moisFr = [
                "January" => "janvier", "February" => "février", "March" => "mars",
                "April" => "avril", "May" => "mai", "June" => "juin",
                "July" => "juillet", "August" => "août", "September" => "septembre",
                "October" => "octobre", "November" => "novembre", "December" => "décembre"
            ];
            $periode = "{$jour} " . ($moisFr[$mois] ?? $mois) . " {$annee}";
        }
    } elseif ($dateFin !== "") {
        $f = DateTime::createFromFormat("Y-m-d", $dateFin);
        if ($f instanceof DateTime) {
            $jour = $f->format("d");
            $mois = $f->format("F");
            $annee = $f->format("Y");
            $moisFr = [
                "January" => "janvier", "February" => "février", "March" => "mars",
                "April" => "avril", "May" => "mai", "June" => "juin",
                "July" => "juillet", "August" => "août", "September" => "septembre",
                "October" => "octobre", "November" => "novembre", "December" => "décembre"
            ];
            $periode = "{$jour} " . ($moisFr[$mois] ?? $mois) . " {$annee}";
        }
    }

    return [
        "numero" => $numero,
        "civilite" => $civilite,
        "neText" => $neText,
        "dateNaissance" => $dateNaissance,
        "lieuNaissance" => trim((string) ($row["lieu_naissance"] ?? "")),
        "today" => $today,
        "periode" => $periode,
    ];
}

function buildQrPayload(array $row, array $viewData): string
{
    $dateNaissance = trim((string) ($viewData["dateNaissance"] ?? ""));
    if ($dateNaissance === "") {
        $dateNaissance = trim((string) ($row["date_naissance"] ?? ""));
    }

    $payload = [
        "no" => (string) ($viewData["numero"] ?? ""),
        "dd" => (string) ($viewData["today"] ?? ""),
        "n" => trim((string) ($row["nom"] ?? "")),
        "p" => trim((string) ($row["prenoms"] ?? "")),
        "dn" => $dateNaissance,
        "ln" => trim((string) ($row["lieu_naissance"] ?? "")),
        "mf" => trim((string) ($row["formation"] ?? "")),
    ];

    $encodedPayload = attestationEncodePayload($payload);
    $signature = attestationSignPayload($encodedPayload);

    if ($encodedPayload === "" || $signature === "") {
        return "";
    }

    return buildVerificationUrl($encodedPayload, $signature);
}

function buildVerificationUrl(string $encodedPayload, string $signature): string
{
    if ($encodedPayload === "" || $signature === "") {
        return "";
    }

    $publicBaseUrl = rtrim(trim((string) getenv("PIS_PUBLIC_BASE_URL")), "/");
    if ($publicBaseUrl !== "") {
        return sprintf(
            "%s/attestations/verify.php?d=%s&s=%s",
            $publicBaseUrl,
            rawurlencode($encodedPayload),
            rawurlencode($signature)
        );
    }

    $isHttps = (!empty($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] !== "off")
        || ((string) ($_SERVER["HTTP_X_FORWARDED_PROTO"] ?? "") === "https")
        || ((string) ($_SERVER["SERVER_PORT"] ?? "") === "443");
    $scheme = $isHttps ? "https" : "http";
    $host = trim((string) ($_SERVER["HTTP_HOST"] ?? ""));

    if ($host === "") {
        $host = "localhost";
    }

    return sprintf(
        "%s://%s/PIS/attestations/verify.php?d=%s&s=%s",
        $scheme,
        $host,
        rawurlencode($encodedPayload),
        rawurlencode($signature)
    );
}

function buildQrCodeDataUri(string $payload): string
{
    $payload = trim($payload);

    if (
        $payload === ""
        || !class_exists(\chillerlan\QRCode\QRCode::class)
        || !class_exists(\chillerlan\QRCode\QROptions::class)
    ) {
        return "";
    }

    try {
        $options = new \chillerlan\QRCode\QROptions([
            "outputType" => \chillerlan\QRCode\QRCode::OUTPUT_MARKUP_SVG,
            "eccLevel" => \chillerlan\QRCode\QRCode::ECC_M,
            "addQuietzone" => true,
            "scale" => 4,
            "imageBase64" => false,
        ]);

        $svg = (new \chillerlan\QRCode\QRCode($options))->render($payload);

        if (str_starts_with($svg, "data:image/")) {
            return $svg;
        }

        return "data:image/svg+xml;base64," . base64_encode($svg);
    } catch (Throwable $e) {
        return "";
    }
}

function buildAttestationDocumentHtml(string $sheetHtml, string $styles): string
{
    return "<!doctype html>\n"
        . "<html lang=\"fr\">\n"
        . "<head>\n"
        . "    <meta charset=\"utf-8\">\n"
        . "    <title>Attestation</title>\n"
        . "    <style>\n"
        . $styles . "\n"
        . "    </style>\n"
        . "</head>\n"
        . "<body>\n"
        . "<div class=\"page\">\n"
        . $sheetHtml . "\n"
        . "</div>\n"
        . "</body>\n"
        . "</html>\n";
}

function ensureDirectoryExists(string $dirPath): bool
{
    if ($dirPath === "") {
        return false;
    }

    if (is_dir($dirPath)) {
        return true;
    }

    return @mkdir($dirPath, 0777, true);
}

function saveAttestationCopies(
    array $row,
    array $viewData,
    string $sheetHtml,
    string $styles,
    string $storageRoot,
    string $productionDate
): void {
    if ($sheetHtml === "" || $styles === "" || $storageRoot === "" || $productionDate === "") {
        return;
    }

    $numero = sanitizeFileName((string) ($viewData["numero"] ?? "attestation"));

    $fileName = sanitizeFileName(
        sprintf(
            "attestation-%s-%s-%s",
            (string) ($row["nom"] ?? ""),
            (string) ($row["prenoms"] ?? ""),
            $numero
        )
    ) . ".html";

    $baseDateDir = rtrim($storageRoot, "\\/") . DIRECTORY_SEPARATOR . $productionDate;
    $moduleName = trim((string) ($row["formation"] ?? ""));
    $htmlDocument = buildAttestationDocumentHtml($sheetHtml, $styles);

    if (ensureDirectoryExists($baseDateDir)) {
        @file_put_contents($baseDateDir . DIRECTORY_SEPARATOR . $fileName, $htmlDocument);
    }

    if ($moduleName !== "") {
        $moduleDir = $baseDateDir . DIRECTORY_SEPARATOR . "par-module" . DIRECTORY_SEPARATOR . sanitizeDirectoryName($moduleName);
        if (ensureDirectoryExists($moduleDir)) {
            @file_put_contents($moduleDir . DIRECTORY_SEPARATOR . $fileName, $htmlDocument);
        }
    }
}

function renderAttestationSheet(
    array $row,
    array $viewData,
    string $logoPath,
    string $watermarkPath,
    string $signataire,
    string $qrCodeDataUri
): string {
    ob_start();
    ?>
    <section class="sheet">
        <?php if ($watermarkPath !== ""): ?>
            <img class="watermark" src="<?= htmlspecialchars($watermarkPath) ?>" alt="">
        <?php endif; ?>
        <div class="sheet-content">
        <div class="main-block">
            <div class="header">
                <div>
                    <?php if ($logoPath !== ""): ?>
                        <img class="logo" src="<?= htmlspecialchars($logoPath) ?>" alt="Logo PIS">
                    <?php endif; ?>
                </div>
                <h1>PÔLE INFORMATIQUE <br>ET SERVICES</h1>
            </div>
            <div class="center-block">
                <h2 class="title">ATTESTATION DE FORMATION</h2>
                <div class="content">
                    Nous, soussignés<strong> MOUTORE Yentougle</strong>, Maître de Conférences de Sociologie urbaine, Chaire UNESCO en TIC et développement de l'enseignement supérieur en Afrique de l'Ouest, deuxième Directeur adjoint des Affaires Académiques et de la Scolarité de l'Université de Kara (Togo), attestons que:
                    <br><Em> <?= htmlspecialchars($viewData["civilite"]) ?></Em> <span class="name-inline"><?= htmlspecialchars((string) ($row["apprenant"] ?? "")) ?></span><br><span class="birth-info"><?php if ($viewData["dateNaissance"] !== ""): ?><?= htmlspecialchars($viewData["neText"]) ?> le <?= htmlspecialchars($viewData["dateNaissance"]) ?><?php endif; ?><?php if ($viewData["lieuNaissance"] !== ""): ?> à <?= htmlspecialchars($viewData["lieuNaissance"]) ?><?php endif; ?>,</span>
                        <div class="training-note">a suivi avec succès, du <?php if ($viewData["periode"] !== ""): ?><?= htmlspecialchars($viewData["periode"]) ?><?php endif; ?>, la formation sur:</div>
                    <div class="module-wrap">
                        <span class="module"><?= htmlspecialchars((string) ($row["formation"] ?? "")) ?></span>
                    </div>
                    Cette attestation lui est délivrée pour servir et valoir ce que de droit.<br>
                    <!-- Date d'inscription : <?= htmlspecialchars((string) ($row["date_inscription"] ?? "")) ?>. -->
                </div>
                <!-- <p class="footer-note">Cette attestation lui est délivrée pour servir et valoir ce que de droit.</p> -->
            </div>
        </div>
        <div class="signature">
            <div class="signature-box">
                <div>Fait à Kara, le <?= htmlspecialchars($viewData["today"]) ?> </div>
                <div class="signature-line"><?= htmlspecialchars($signataire) ?></div>
            </div>
        </div>
        <div class="meta-bottom">
            <?php if ($qrCodeDataUri !== ""): ?>
                <div class="qr-wrap">
                    <img class="attestation-qr" src="<?= htmlspecialchars($qrCodeDataUri) ?>" alt="QR code de verification">
                </div>
            <?php endif; ?>
            <div class="meta-line">No : <?= htmlspecialchars($viewData["numero"]) ?> Date de delivrance : <?= htmlspecialchars($viewData["today"]) ?></div>
        </div>
        <div class="institution-footer">
            PRESIDENCE: Route N°1 B.P.:404 Email: presidence@univkara.tg Kara-Togo Campus Sud : Route ENI B.P. :43 Kara-Togo Tél.:(228) 26601269 Email : daas@univkara.tg
        </div>
        </div>
    </section>
    <?php
    return (string) ob_get_clean();
}

$attestationStyles = <<<'CSS'
* { box-sizing: border-box; }
body { font-family: "Times New Roman", serif; margin: 0; background: #f8fafc; color: #0f172a; }
.page { padding: 8px; }
.sheet { position: relative; background: #fff; border: 10px double #0f172a; padding: 18px 24px; margin-bottom: 8px; page-break-after: always; min-height: 620px; height: 620px; display: flex; flex-direction: column; justify-content: space-between; overflow: hidden; }
.sheet:last-child { page-break-after: auto; }
.watermark { position: absolute; left: 50%; top: 52%; transform: translate(-50%, -50%); width: 620px; opacity: 0.08; z-index: 0; pointer-events: none; }
.sheet-content { position: relative; z-index: 2; display: flex; flex-direction: column; min-height: 100%; height: 100%; }
.sheet-content > div:first-child { flex: 1; }
.main-block { display: flex; flex-direction: column; min-height: 0; }
.center-block { flex: 1; display: flex; flex-direction: column; justify-content: center; }
.header { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; }
.logo { width: 280px; height: auto; display: block; margin: 0; }
.header h1 { margin: 4px 0 0; font-size: 29px; letter-spacing: 1px; text-align: center; }
.title { text-align: center; margin: 30px 0 8px; font-size: 31px; letter-spacing: 1px; text-decoration: underline; }
.subtitle { text-align: center; margin: 0 0 18px; font-size: 16px; }
.content { text-align: center; font-size: 19px; line-height: 1.32; margin-top: 8px; }
.name-inline { font-size: 35px; font-weight: 700; text-transform: uppercase; }    
.training-note { margin: 18px 0 10px; font-size: 22px; font-weight: 400; line-height: 1.3; }    .birth-info { font-weight: 400; }.module-wrap { margin: 14px 0 10px; text-align: center; }
.module { font-style: uppercase; font-weight: 600; font-size: 26px; line-height: 1.15; text-transform: uppercase; display: inline-block; text-align: center; max-width: 74%; }
.identity { margin: 0 0 8px; font-size: 16px; }
.footer-note { text-align: center; margin-top: 12px; font-size: 15px; }
.signature { margin-top: 10px; display: flex; justify-content: flex-end; }
.signature-box { width: 280px; text-align: center; }
.signature-line { margin-top: 42px; padding-top: 8px; min-height: 24px; }
.meta-bottom { margin-top: 10px; text-align: left; font-size: 13px; position: relative; }
.qr-wrap { position: absolute; left: 0; bottom: calc(100% + 4px); margin: 0; }
.attestation-qr { width: 96px; height: 96px; display: block; }
.meta-line { line-height: 1.2; }
.institution-footer { margin-top: 8px; text-align: center; font-size: 12px; line-height: 1.35; border-top: 1px solid #0f172a; padding-top: 6px; }
@media print {
    @page { size: A4 landscape; margin: 5mm; }
    body { background: #fff; }
    .page { padding: 0; }
    .sheet { margin-bottom: 0; height: 200mm; min-height: 200mm; }
}
CSS;
?>
<!doctype html>
<html lang="fr">
<head>
    <meta charset="utf-8">
    <title>Attestations</title>
    <style>
        <?= $attestationStyles ?>
    </style>
</head>
<body>
<div class="page">
<?php if ($isEmpty): ?>
    <section class="sheet" style="min-height:auto;">
        <?php if ($watermarkPath !== ""): ?>
            <img class="watermark" src="<?= htmlspecialchars($watermarkPath) ?>" alt="">
        <?php endif; ?>
        <div class="sheet-content">
        <div class="header">
            <div>
                <?php if ($logoPath !== ""): ?>
                    <img class="logo" src="<?= htmlspecialchars($logoPath) ?>" alt="Logo PIS">
                <?php endif; ?>
            </div>
            <h1>PÔLE INFORMATIQUE ET SERVICES</h1>
        </div>
        <h2 class="title">AUCUNE ATTESTATION A GENERER</h2>
        <p class="subtitle">
            <?php if ($mode === "module" && $formationId <= 0): ?>
                Veuillez selectionner un module de formation avant l'export.
            <?php elseif ($mode === "person" && $stagiaireId <= 0): ?>
                Veuillez selectionner une personne avant l'export.
            <?php elseif ($mode === "module"): ?>
                Aucun apprenant inscrit dans ce module pour le moment.
            <?php elseif ($mode === "person"): ?>
                Aucune attestation trouvee pour cette personne.
            <?php else: ?>
                Aucun apprenant inscrit trouve pour le moment.
            <?php endif; ?>
        </p>
        </div>
    </section>
<?php else: ?>
<?php foreach ($rows as $idx => $r): ?>
    <?php
    $viewData = formatAttestationData($r, $idx, $today);
    $qrPayload = buildQrPayload($r, $viewData);
    $qrCodeDataUri = buildQrCodeDataUri($qrPayload);
    $sheetHtml = renderAttestationSheet($r, $viewData, $logoPath, $watermarkPath, $signataire, $qrCodeDataUri);
    saveAttestationCopies($r, $viewData, $sheetHtml, $attestationStyles, $storageRoot, $productionDate);
    ?>
    <?= $sheetHtml ?>
<?php endforeach; ?>
<?php endif; ?>
</div>
<?php if (!$isEmpty): ?>
<script>window.print()</script>
<?php endif; ?>
</body>
</html>
