<br />
<b>Warning</b>:  Undefined variable $auth in <b>/home/pevo0181/public_html/pia-soft.com/cleania/routes/index.php</b> on line <b>542</b><br />
<br />
<b>Warning</b>:  Trying to access array offset on value of type null in <b>/home/pevo0181/public_html/pia-soft.com/cleania/routes/index.php</b> on line <b>542</b><br />
<?php
// ============================================================
//  PIASCHOOL — send_notification.php
//  API complète notifications push FCM V1
//  Déposer dans : https://pia-soft.com/piaschool/piaschool1/
// ============================================================
error_reporting(0);
ini_set('display_errors', 0);

define('DB_HOST', 'localhost');
define('DB_NAME', 'pevo0181_piaschool1');
define('DB_USER', 'pevo0181_piaschool1');
define('DB_PASS', 'Piasoft2021');
define('FIREBASE_CREDENTIALS', __DIR__ . '/firebase-credentials.json');
define('FIREBASE_PROJECT_ID', 'piaschool-b9da8');
define('SYNC_TOKEN', 'Pia2026xK9mZqR7vLSnW4');

header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(200); exit(); }

// ── Connexion DB
try {
    $pdo = new PDO(
        "mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=utf8mb4",
        DB_USER, DB_PASS,
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
         PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]
    );
} catch (Exception $e) {
    echo json_encode(['success' => false, 'message' => 'Erreur DB: ' . $e->getMessage()]);
    exit();
}

// ── Vérifier token (GET ou header)
$token = str_replace('Bearer ', '', $_SERVER['HTTP_AUTHORIZATION'] ?? $_GET['token'] ?? '');
if ($token !== SYNC_TOKEN) {
    $stmt = $pdo->prepare("SELECT id FROM api_tokens WHERE token = ? AND actif = 1");
    $stmt->execute([$token]);
    if (!$stmt->fetch()) {
        http_response_code(401);
        echo json_encode(['success' => false, 'message' => 'Token invalide']);
        exit();
    }
}

// ── Router
$method = $_SERVER['REQUEST_METHOD'];
$action = $_GET['action'] ?? '';
$body   = json_decode(file_get_contents('php://input'), true) ?? [];

// GET actions
if ($method === 'GET') {
    switch ($action) {
        case 'test':     actionTest($pdo);          break;
        case 'historique': actionHistorique($pdo);  break;
        case 'ping':     echo json_encode(['success' => true, 'message' => 'Piaschool FCM V1 operationnel']); break;
        default: echo json_encode(['success' => true, 'message' => 'Piaschool FCM V1 Service operationnel']);
    }
    exit();
}

// POST actions
switch ($body['type'] ?? $action) {
    case 'arrivee':    actionArrivee($pdo, $body);    break;
    case 'absence':    actionAbsence($pdo, $body);    break;
    case 'bulletin':   actionBulletin($pdo, $body);   break;
    case 'pension':    actionPension($pdo, $body);     break;
    case 'impayes':    actionImpayes($pdo);             break;
    case 'diffusion':
    case 'broadcast':  actionDiffusion($pdo, $body);   break;
    case 'historique': actionHistorique($pdo);          break;
    case 'test':       actionTest($pdo, $body);         break;
    default: echo json_encode(['success' => false, 'message' => 'Action inconnue']);
}

// ════════════════════════════════════════════════════════════
//  ACTIONS
// ════════════════════════════════════════════════════════════

function actionArrivee($pdo, $body) {
    $eleveId  = intval($body['eleve_id'] ?? 0);
    $datetime = $body['datetime'] ?? date('Y-m-d H:i:s');
    if (!$eleveId) { echo json_encode(['success' => false, 'message' => 'eleve_id requis']); return; }

    $stmt = $pdo->prepare("SELECT nom, prenom FROM eleves WHERE id = ?");
    $stmt->execute([$eleveId]);
    $eleve = $stmt->fetch();
    if (!$eleve) { echo json_encode(['success' => false, 'message' => 'Eleve introuvable']); return; }

    $heure   = date('H:i', strtotime($datetime));
    $titre   = "Arrivee a l'ecole";
    $message = "{$eleve['prenom']} est arrive(e) a l'ecole a $heure. Bonne journee !";

    $res = envoyerNotification($pdo, 'P_'.$eleveId, $eleveId, 'arrivee', $titre, $message,
        ['heure' => $heure, 'eleve_id' => (string)$eleveId]);
    echo json_encode(['success' => $res['success'] ?? false, 'sent' => $res['success'] ? 1 : 0]);
}

function actionAbsence($pdo, $body) {
    $eleveId = intval($body['eleve_id'] ?? 0);
    $periode = $body['periode'] ?? 'matin';
    $date    = $body['date']    ?? date('Y-m-d');
    if (!$eleveId) { echo json_encode(['success' => false, 'message' => 'eleve_id requis']); return; }

    $stmt = $pdo->prepare("SELECT nom, prenom FROM eleves WHERE id = ?");
    $stmt->execute([$eleveId]);
    $eleve = $stmt->fetch();
    if (!$eleve) { echo json_encode(['success' => false, 'message' => 'Eleve introuvable']); return; }

    $dateF    = date('d/m/Y', strtotime($date));
    $periodeF = $periode === 'matin' ? 'ce matin' : 'cet apres-midi';
    $titre    = "Absence signalee";
    $message  = "{$eleve['prenom']} a ete marque(e) absent(e) $periodeF ($dateF).";

    $res = envoyerNotification($pdo, 'P_'.$eleveId, $eleveId, 'absence', $titre, $message,
        ['date' => $date, 'periode' => $periode, 'eleve_id' => (string)$eleveId]);
    echo json_encode(['success' => $res['success'] ?? false, 'sent' => $res['success'] ? 1 : 0]);
}

function actionBulletin($pdo, $body) {
    $eleveId   = intval($body['eleve_id']   ?? 0);
    $sessionId = intval($body['session_id'] ?? 0);
    $moyenne   = $body['moyenne']  ?? '';
    $rang      = $body['rang']     ?? '';
    $effectif  = $body['effectif'] ?? '';
    if (!$eleveId) { echo json_encode(['success' => false, 'message' => 'eleve_id requis']); return; }

    $stmt = $pdo->prepare("SELECT e.nom, e.prenom, s.nom_fr AS session_nom FROM eleves e LEFT JOIN sessions_evaluation s ON s.id = ? WHERE e.id = ?");
    $stmt->execute([$sessionId, $eleveId]);
    $data = $stmt->fetch();
    if (!$data) { echo json_encode(['success' => false, 'message' => 'Eleve introuvable']); return; }

    $session = $data['session_nom'] ?? 'cette sequence';
    $titre   = "Bulletin disponible";
    $message = "Le bulletin de {$data['prenom']} pour $session est disponible."
             . ($moyenne ? " Moyenne: $moyenne/20" : "")
             . ($rang && $effectif ? " - Rang: $rang/$effectif" : "")
             . ". Consultez l'application Piaschool.";

    $res = envoyerNotification($pdo, 'P_'.$eleveId, $eleveId, 'bulletin', $titre, $message,
        ['session_id' => (string)$sessionId, 'moyenne' => (string)$moyenne, 'eleve_id' => (string)$eleveId]);
    echo json_encode(['success' => $res['success'] ?? false, 'sent' => $res['success'] ? 1 : 0]);
}

function actionPension($pdo, $body) {
    $eleveId = intval($body['eleve_id'] ?? 0);
    $montant = floatval($body['montant'] ?? 0);
    $tranche = intval($body['tranche']  ?? 1);
    $recu    = $body['recu'] ?? '';
    $reste   = $body['reste'] ?? null;
    if (!$eleveId) { echo json_encode(['success' => false, 'message' => 'eleve_id requis']); return; }

    $stmt = $pdo->prepare("SELECT nom, prenom FROM eleves WHERE id = ?");
    $stmt->execute([$eleveId]);
    $eleve = $stmt->fetch();
    if (!$eleve) { echo json_encode(['success' => false, 'message' => 'Eleve introuvable']); return; }

    $mntF    = number_format($montant, 0, ',', ' ');
    $titre   = "Paiement pension recu";
    $message = "Paiement de $mntF FCFA recu (Tranche $tranche) pour {$eleve['prenom']}."
             . ($recu ? " Recu: $recu." : "")
             . ($reste !== null && floatval($reste) > 0
                ? " Reste: " . number_format(floatval($reste), 0, ',', ' ') . " FCFA."
                : " Compte solde !");

    $res = envoyerNotification($pdo, 'P_'.$eleveId, $eleveId, 'paiement', $titre, $message,
        ['montant' => (string)$montant, 'tranche' => (string)$tranche, 'eleve_id' => (string)$eleveId]);
    echo json_encode(['success' => $res['success'] ?? false, 'sent' => $res['success'] ? 1 : 0]);
}

function actionImpayes($pdo) {
    $stmt = $pdo->query("
        SELECT e.id AS eleve_id, e.nom, e.prenom,
               pc.montant_total,
               COALESCE(SUM(pp.montant_paye), 0) AS total_paye,
               (pc.montant_total - COALESCE(SUM(pp.montant_paye), 0)) AS reste
        FROM eleves e
        JOIN inscriptions i ON i.eleve_id = e.id
        JOIN pension_config pc ON pc.niveau_id = (SELECT niveau_id FROM classes WHERE id = i.classe_id)
            AND pc.annee_id = i.annee_id
        LEFT JOIN pension_paiements pp ON pp.inscription_id = i.id
        JOIN annees_scolaires a ON a.id = i.annee_id AND a.active = 1
        WHERE e.statut = 'actif'
        GROUP BY e.id, pc.montant_total
        HAVING reste > 0
        ORDER BY reste DESC
    ");
    $impayes   = $stmt->fetchAll();
    $totalSent = 0;

    foreach ($impayes as $imp) {
        $resteF  = number_format(floatval($imp['reste']), 0, ',', ' ');
        $titre   = "Rappel pension scolaire";
        $message = "Rappel: un solde de $resteF FCFA est en attente pour {$imp['prenom']}. Merci de regulariser.";
        $res = envoyerNotification($pdo, 'P_'.$imp['eleve_id'], $imp['eleve_id'], 'pension', $titre, $message,
            ['eleve_id' => (string)$imp['eleve_id'], 'reste' => (string)$imp['reste']]);
        if ($res['success'] ?? false) $totalSent++;
    }

    echo json_encode(['success' => true, 'impayes' => count($impayes), 'sent' => $totalSent]);
}

function actionDiffusion($pdo, $body) {
    $titre    = trim($body['titre']   ?? '');
    $message  = trim($body['message'] ?? '');
    $cible    = $body['cible']    ?? 'tous';
    $classeId = intval($body['classe_id'] ?? 0);

    if (!$titre || !$message) {
        echo json_encode(['success' => false, 'message' => 'Titre et message requis']);
        return;
    }

    // Récupérer tous les tokens FCM selon la cible
    if ($cible === 'classe' && $classeId > 0) {
        $stmt = $pdo->prepare("
            SELECT DISTINCT CONCAT('P_', e.id) AS parent_id, ft.fcm_token
            FROM eleves e
            JOIN inscriptions i ON i.eleve_id = e.id
            JOIN fcm_tokens ft ON ft.parent_id = CONCAT('P_', e.id)
            WHERE i.classe_id = ? AND e.statut = 'actif'
        ");
        $stmt->execute([$classeId]);
    } else {
        $stmt = $pdo->query("
            SELECT DISTINCT CONCAT('P_', e.id) AS parent_id, ft.fcm_token
            FROM eleves e
            JOIN inscriptions i ON i.eleve_id = e.id
            JOIN annees_scolaires a ON a.id = i.annee_id AND a.active = 1
            JOIN fcm_tokens ft ON ft.parent_id = CONCAT('P_', e.id)
            WHERE e.statut = 'actif'
        ");
    }
    $tokens = $stmt->fetchAll();

    $sent = 0;
    foreach ($tokens as $t) {
        if (empty($t['fcm_token'])) continue;
        $res = envoyerFCM($t['fcm_token'], $titre, $message, ['type' => 'diffusion']);
        if ($res['success']) $sent++;
    }

    // Sauvegarder historique
    try {
        $pdo->exec("CREATE TABLE IF NOT EXISTS push_diffusions (
            id INT AUTO_INCREMENT PRIMARY KEY,
            titre VARCHAR(200), message TEXT,
            cible VARCHAR(20), classe_id INT DEFAULT NULL,
            classe_nom VARCHAR(100) DEFAULT NULL,
            sent INT DEFAULT 0,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

        $classeNom = '';
        if ($classeId > 0) {
            $sc = $pdo->prepare("SELECT nom FROM classes WHERE id = ?");
            $sc->execute([$classeId]);
            $classeNom = $sc->fetchColumn() ?: '';
        }
        $pdo->prepare("INSERT INTO push_diffusions (titre,message,cible,classe_id,classe_nom,sent) VALUES (?,?,?,?,?,?)")
            ->execute([$titre, $message, $cible, $classeId ?: null, $classeNom, $sent]);
    } catch(Exception $e) {}

    echo json_encode(['success' => true, 'sent' => $sent, 'total' => count($tokens)]);
}

function actionHistorique($pdo) {
    try {
        $pdo->exec("CREATE TABLE IF NOT EXISTS push_diffusions (
            id INT AUTO_INCREMENT PRIMARY KEY,
            titre VARCHAR(200), message TEXT,
            cible VARCHAR(20), classe_id INT DEFAULT NULL,
            classe_nom VARCHAR(100) DEFAULT NULL,
            sent INT DEFAULT 0,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
        $stmt = $pdo->query("SELECT * FROM push_diffusions ORDER BY created_at DESC LIMIT 30");
        echo json_encode(['success' => true, 'data' => $stmt->fetchAll()]);
    } catch(Exception $e) {
        echo json_encode(['success' => true, 'data' => []]);
    }
}

function actionTest($pdo, $body = []) {
    $fcmToken = $body['token'] ?? '';
    if (!$fcmToken) {
        $stmt = $pdo->query("SELECT fcm_token FROM fcm_tokens LIMIT 1");
        $row  = $stmt->fetch();
        $fcmToken = $row['fcm_token'] ?? '';
    }
    if (!$fcmToken) { echo json_encode(['success' => false, 'message' => 'Aucun token FCM']); return; }

    $titre   = $body['titre']   ?? 'Test Piaschool';
    $message = $body['message'] ?? 'La notification push fonctionne correctement !';
    $result  = envoyerFCM($fcmToken, $titre, $message, ['type' => 'test']);
    echo json_encode(['success' => $result['success'], 'fcm_response' => $result]);
}

// ════════════════════════════════════════════════════════════
//  FONCTIONS CORE (du fichier qui fonctionne)
// ════════════════════════════════════════════════════════════

function envoyerNotification($pdo, $parentId, $eleveId, $type, $titre, $message, $data = []) {
    // Sauvegarder en base
    try {
        $pdo->exec("CREATE TABLE IF NOT EXISTS mobile_notifications (
            id INT AUTO_INCREMENT PRIMARY KEY,
            parent_id VARCHAR(50), eleve_id INT,
            type VARCHAR(50), titre VARCHAR(200),
            message TEXT, data JSON, lu TINYINT(1) DEFAULT 0,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            INDEX parent_id (parent_id)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
        $stmt = $pdo->prepare("INSERT INTO mobile_notifications (parent_id, eleve_id, type, titre, message, data) VALUES (?, ?, ?, ?, ?, ?)");
        $stmt->execute([$parentId, $eleveId, $type, $titre, $message, json_encode($data)]);
    } catch(Exception $e) {}

    // Récupérer token FCM
    $tokenStmt = $pdo->prepare("SELECT fcm_token FROM fcm_tokens WHERE parent_id = ?");
    $tokenStmt->execute([$parentId]);
    $fcmToken  = $tokenStmt->fetchColumn();

    if (!$fcmToken) return ['success' => false, 'message' => 'Token FCM non trouve'];

    return envoyerFCM($fcmToken, $titre, $message, array_merge($data, [
        'type'      => $type,
        'parent_id' => $parentId,
        'eleve_id'  => (string)$eleveId,
    ]));
}

function envoyerFCM($fcmToken, $titre, $message, $data = []) {
    $accessToken = getAccessToken();
    if (!$accessToken) return ['success' => false, 'message' => 'Token invalide'];

    $dataStr = [];
    foreach ($data as $k => $v) $dataStr[(string)$k] = (string)$v;

    $payload = json_encode([
        'message' => [
            'token'        => $fcmToken,
            'notification' => ['title' => $titre, 'body' => $message],
            'data'         => $dataStr,
            'android'      => [
                'priority'     => 'high',
                'notification' => ['channel_id' => 'piaschool_channel', 'sound' => 'default'],
            ],
        ]
    ]);

    $url = "https://fcm.googleapis.com/v1/projects/" . FIREBASE_PROJECT_ID . "/messages:send";
    $ch  = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json',
        'Authorization: Bearer ' . $accessToken,
    ]);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $result   = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    return ['success' => $httpCode === 200, 'http_code' => $httpCode, 'response' => json_decode($result, true)];
}

function getAccessToken() {
    $credentials = json_decode(file_get_contents(FIREBASE_CREDENTIALS), true);
    $now = time();
    $header  = base64url_encode(json_encode(['alg' => 'RS256', 'typ' => 'JWT']));
    $payload = base64url_encode(json_encode([
        'iss'   => $credentials['client_email'],
        'scope' => 'https://www.googleapis.com/auth/firebase.messaging',
        'aud'   => 'https://oauth2.googleapis.com/token',
        'iat'   => $now,
        'exp'   => $now + 3600,
    ]));
    $signingInput = "$header.$payload";
    openssl_sign($signingInput, $signature, $credentials['private_key'], 'SHA256');
    $jwt = "$header.$payload." . base64url_encode($signature);

    $ch = curl_init('https://oauth2.googleapis.com/token');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
        'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
        'a