<?php
/**
 * CMS actualités — création, édition, publication et lecture des actualités
 * de l'ISIT (Tâche 12) — et CMS médias/galerie, groupés par album (Tâche 13).
 *
 * Toutes les fonctions sont pures vis-à-vis du disque (aucun accès fichier
 * ici) : l'image n'est ici qu'un nom de fichier (colonne `image`), son
 * enregistrement/suppression sur uploads/actus/ est à la charge de l'appelant
 * (public/admin/actualites.php), exactement comme enregistrer_piece() gère le
 * disque séparément de la couche candidatures.
 */

if (!function_exists('cms_creer_actualite')) {
    /**
     * Crée une actualité (publiée par défaut, comme le prévoit le schéma) et
     * retourne son id.
     */
    function cms_creer_actualite(PDO $pdo, string $titre, string $contenu, ?string $image): int {
        $pdo->prepare('INSERT INTO actualites (titre, contenu, image) VALUES (?,?,?)')
            ->execute([$titre, $contenu, $image]);
        return (int)$pdo->lastInsertId();
    }
}

if (!function_exists('cms_modifier_actualite')) {
    /**
     * Modifie le titre/contenu d'une actualité existante. $image à null
     * conserve l'image déjà en base (COALESCE) : seul un appelant qui a
     * effectivement reçu un nouveau fichier doit passer une valeur non nulle.
     */
    function cms_modifier_actualite(PDO $pdo, int $id, string $titre, string $contenu, ?string $image): void {
        $pdo->prepare('UPDATE actualites SET titre = ?, contenu = ?, image = COALESCE(?, image) WHERE id = ?')
            ->execute([$titre, $contenu, $image, $id]);
    }
}

if (!function_exists('cms_publier_actualite')) {
    /** Publie ou dépublie une actualité (n'efface rien : voir cms_supprimer_actualite). */
    function cms_publier_actualite(PDO $pdo, int $id, bool $publie): void {
        $pdo->prepare('UPDATE actualites SET publie = ? WHERE id = ?')->execute([(int)$publie, $id]);
    }
}

if (!function_exists('cms_supprimer_actualite')) {
    /** Supprime définitivement une actualité (ligne base uniquement, voir note d'en-tête). */
    function cms_supprimer_actualite(PDO $pdo, int $id): void {
        $pdo->prepare('DELETE FROM actualites WHERE id = ?')->execute([$id]);
    }
}

if (!function_exists('cms_decorer_actualite')) {
    /**
     * Ajoute aux colonnes brutes de la table les champs calculés attendus par
     * les vues : `date` (d/m/Y) et `resume` (extrait de contenu, ~180
     * caractères suivis de « … » si tronqué). Centralisé ici pour que
     * l'accueil, la liste publique et l'admin affichent toujours la même
     * date et le même extrait.
     */
    function cms_decorer_actualite(array $row): array {
        // Revue Task 12 : created_at absent ou illisible => date vide, pas le
        // « 01/01/1970 » que produirait date() nourri d'un strtotime() en échec.
        $ts = strtotime((string)($row['created_at'] ?? ''));
        $row['date'] = $ts ? date('d/m/Y', $ts) : '';
        $contenu = (string)$row['contenu'];
        $row['resume'] = mb_strlen($contenu) > 180 ? mb_substr($contenu, 0, 180) . ' …' : $contenu;
        return $row;
    }
}

if (!function_exists('cms_actualite')) {
    /** Lecture publique : uniquement une actualité publiée (sinon null — 404 côté routeur). */
    function cms_actualite(PDO $pdo, int $id): ?array {
        $q = $pdo->prepare('SELECT * FROM actualites WHERE id = ? AND publie = 1');
        $q->execute([$id]);
        $row = $q->fetch();
        return $row === false ? null : cms_decorer_actualite($row);
    }
}

if (!function_exists('cms_actualite_admin')) {
    /** Lecture admin : n'importe quel état (pour l'édition d'un brouillon dépublié). */
    function cms_actualite_admin(PDO $pdo, int $id): ?array {
        $q = $pdo->prepare('SELECT * FROM actualites WHERE id = ?');
        $q->execute([$id]);
        $row = $q->fetch();
        return $row === false ? null : cms_decorer_actualite($row);
    }
}

if (!function_exists('cms_actualites_recentes')) {
    /**
     * Actualités publiées, plus récentes d'abord — created_at puis id en
     * repli pour un ordre stable même quand plusieurs lignes partagent la
     * même seconde (résolution de CURRENT_TIMESTAMP). Utilisée à la fois par
     * le bloc d'accueil (3) et la liste publique paginée (9/page).
     */
    function cms_actualites_recentes(PDO $pdo, int $n, int $offset = 0): array {
        $q = $pdo->prepare('SELECT * FROM actualites WHERE publie = 1 ORDER BY created_at DESC, id DESC LIMIT :n OFFSET :offset');
        $q->bindValue(':n', $n, PDO::PARAM_INT);
        $q->bindValue(':offset', $offset, PDO::PARAM_INT);
        $q->execute();
        return array_map('cms_decorer_actualite', $q->fetchAll());
    }
}

if (!function_exists('cms_actualites_admin')) {
    /** Toutes les actualités (y compris dépubliées), plus récentes d'abord — tableau d'administration. */
    function cms_actualites_admin(PDO $pdo): array {
        $rows = $pdo->query('SELECT * FROM actualites ORDER BY created_at DESC, id DESC')->fetchAll();
        return array_map('cms_decorer_actualite', $rows);
    }
}

if (!function_exists('cms_compter_actualites')) {
    /** Nombre total d'actualités publiées — pagination de la liste publique. */
    function cms_compter_actualites(PDO $pdo): int {
        return (int)$pdo->query('SELECT COUNT(*) FROM actualites WHERE publie = 1')->fetchColumn();
    }
}

/*
 * --- Médias (galerie) — Tâche 13 ---
 *
 * Même séparation des responsabilités que les actualités ci-dessus : ces
 * fonctions sont pures vis-à-vis du disque (aucun accès fichier ici) —
 * `fichier` n'est qu'un nom de fichier stocké en base ; l'enregistrement et
 * la suppression sur uploads/medias/ restent à la charge de l'appelant
 * (public/admin/medias.php).
 */

if (!function_exists('cms_ajouter_media')) {
    /** Ajoute un média à un album et retourne son id. */
    function cms_ajouter_media(PDO $pdo, string $album, string $fichier, ?string $legende, int $position = 0): int {
        $pdo->prepare('INSERT INTO medias (album, fichier, legende, position) VALUES (?,?,?,?)')
            ->execute([$album, $fichier, $legende, $position]);
        return (int)$pdo->lastInsertId();
    }
}

if (!function_exists('cms_supprimer_media')) {
    /** Supprime définitivement un média (ligne base uniquement, voir note d'en-tête). */
    function cms_supprimer_media(PDO $pdo, int $id): void {
        $pdo->prepare('DELETE FROM medias WHERE id = ?')->execute([$id]);
    }
}

if (!function_exists('cms_media')) {
    /** Lecture d'un média par id (formulaire de suppression : retrouver le fichier à effacer du disque). */
    function cms_media(PDO $pdo, int $id): ?array {
        $q = $pdo->prepare('SELECT * FROM medias WHERE id = ?');
        $q->execute([$id]);
        $row = $q->fetch();
        return $row === false ? null : $row;
    }
}

if (!function_exists('cms_medias_par_album')) {
    /**
     * Tous les médias, groupés par album (clé = nom d'album, dans l'ordre
     * alphabétique) puis par position croissante au sein de chaque album
     * (id en repli pour un ordre stable entre médias de même position).
     */
    function cms_medias_par_album(PDO $pdo): array {
        $rows = $pdo->query('SELECT * FROM medias ORDER BY album, position, id')->fetchAll();
        $albums = [];
        foreach ($rows as $row) {
            $albums[$row['album']][] = $row;
        }
        return $albums;
    }
}
