<?php
/**
 * Admin — Abonnements aux rapports par e-mail.
 *
 * Section 1 : Planification des rapports (fréquence, jour, heure, enabled)
 * Section 2 : Matrice utilisateurs × rapports (checkboxes)
 *
 * Accès : app_admin uniquement.
 */
require_once dirname(__DIR__) . '/bootstrap.php';
$auth->requireRole(ROLE_APP_ADMIN);

if (!Session::has('csrf_token')) {
    Session::set('csrf_token', bin2hex(random_bytes(32)));
}

/*
 * ── Les rapports des modules ACTIFS, et eux seuls ────────────────────────
 *
 * Chaque rapport declare le module dont il depend (ReportRenderer::REPORTS,
 * clef `module`). Proposer le rapport d'un module desactive n'a pas de sens :
 * ReportRenderer::render() irait interroger un module qu'on a justement
 * eteint.
 *
 * ATTENTION — cette liste sert AUSSI a la sauvegarde, et c'est indispensable.
 * Le gestionnaire POST ci-dessous parcourait ReportRenderer::REPORTS en
 * entier et effacait toute la table des abonnes avant de la reconstruire
 * depuis le formulaire. Filtrer le seul AFFICHAGE aurait donc, au premier
 * enregistrement :
 *   - remis a `enabled = 0` et `frequency = daily` la planification de tout
 *     rapport masque, puisque rien n'est poste pour lui ;
 *   - supprime tous ses abonnes.
 * Desactiver un module temporairement aurait ainsi detruit sa configuration
 * en silence. La sauvegarde est donc bornee, elle aussi, a ce qui a ete
 * REELLEMENT propose.
 */
$reports = array_filter(
    ReportRenderer::REPORTS,
    fn(array $meta) => $moduleRegistry->isActive($meta['module'] ?? '')
);

/* ── POST : sauvegarde ────────────────────────────────────────────────── */
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!hash_equals(Session::get('csrf_token', ''), $_POST['csrf_token'] ?? '')) {
        Session::setFlash('error', t('msg.error'));
        header('Location: /admin/report_subscriptions.php'); exit;
    }

    // Sauvegarder les planifications — uniquement celles qui etaient au
    // formulaire. Un rapport masque garde la sienne intacte.
    foreach ($reports as $rk => $meta) {
        $freq    = $_POST["freq_{$rk}"]   ?? 'daily';
        $tod     = $_POST["time_{$rk}"]   ?? '08:00';
        $enabled = isset($_POST["enabled_{$rk}"]) ? 1 : 0;

        // Construire day_config JSON
        $dc = null;
        if ($freq === 'weekly') {
            $dc = json_encode(['dow' => (int)($_POST["dow_{$rk}"] ?? 1)]);
        } elseif ($freq === 'monthly') {
            $mtype = $_POST["mtype_{$rk}"] ?? 'numeric';
            if ($mtype === 'logical') {
                $dc = json_encode(['logical' => $_POST["logical_{$rk}"] ?? 'first_monday']);
            } else {
                $dc = json_encode(['dom' => (int)($_POST["dom_{$rk}"] ?? 1)]);
            }
        }

        $db->execute(
            "UPDATE report_schedules SET frequency = ?, day_config = ?, time_of_day = ?, enabled = ?, updated_at = datetime('now') WHERE report_key = ?",
            [$freq, $dc, $tod, $enabled, $rk]
        );
    }

    /* Sauvegarder les abonnements : on efface puis on reinsere, mais SEULEMENT
       pour les rapports qui etaient au formulaire. Un DELETE sans clause
       emporterait les abonnes des rapports masques. */
    $visibles = array_keys($reports);
    if ($visibles !== []) {
        $ph = implode(',', array_fill(0, count($visibles), '?'));
        $db->execute("DELETE FROM report_subscribers WHERE report_key IN ($ph)", $visibles);
    }
    $subs = $_POST['sub'] ?? [];
    foreach ($subs as $rk => $userIds) {
        if (!isset($reports[$rk])) continue;
        foreach ($userIds as $uid => $on) {
            $db->execute(
                "INSERT OR IGNORE INTO report_subscribers (report_key, user_id) VALUES (?, ?)",
                [$rk, (int)$uid]
            );
        }
    }

    Session::setFlash('success', t('report_sub.saved'));
    header('Location: /admin/report_subscriptions.php'); exit;
}

/* ── Données ──────────────────────────────────────────────────────────── */
$schedules = [];
foreach ($db->fetchAll("SELECT * FROM report_schedules ORDER BY report_key") as $r) {
    $schedules[$r['report_key']] = $r;
}

$subscribers = [];
foreach ($db->fetchAll("SELECT report_key, user_id FROM report_subscribers") as $r) {
    $subscribers[$r['report_key']][$r['user_id']] = true;
}

$users = $db->fetchAll(
    "SELECT id, username, email FROM users WHERE active = 1 AND email IS NOT NULL AND email != '' ORDER BY username"
);

$dowNames = [];
for ($d = 1; $d <= 7; $d++) $dowNames[$d] = t("report_sub.dow_{$d}");

$logicalOptions = [
    'first_monday'  => t('report_sub.logical_first_monday'),
    'first_tuesday' => t('report_sub.logical_first_tuesday'),
    'first_wednesday'=> t('report_sub.logical_first_wednesday'),
    'first_thursday'=> t('report_sub.logical_first_thursday'),
    'first_friday'  => t('report_sub.logical_first_friday'),
    'last_monday'   => t('report_sub.logical_last_monday'),
    'last_friday'   => t('report_sub.logical_last_friday'),
    'last_day'      => t('report_sub.logical_last_day'),
];

$lastSends = $db->fetchAll(
    "SELECT report_key, sent_at, recipient_count, status, details
     FROM report_send_log ORDER BY sent_at DESC LIMIT 10"
);

/* ── Rendu ────────────────────────────────────────────────────────────── */
View::display(__DIR__ . '/views/report_subscriptions.php', [
    'schedules'      => $schedules,
    'subscribers'    => $subscribers,
    'users'          => $users,
    'reports'        => $reports,
    'dowNames'       => $dowNames,
    'logicalOptions' => $logicalOptions,
    'lastSends'      => $lastSends,
]);
