<?php
// ============================================
// SEN RDV SANTÉ+ — Annulation d'un RDV
// POST /api/rdv/annuler.php
// Headers: Authorization: Bearer {token}
// Body: { "rdv_id": 1, "raison": "Empêchement personnel" }
// ============================================

require_once '../config/helpers.php';
require_once '../config/database.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    repondre(['erreur' => 'Méthode non autorisée'], 405);
}

$userConnecte = verifierToken();
$body         = getBody();
validerChamps($body, ['rdv_id']);

$db = getDB();

// je récupère le RDV avec les infos nécessaires
$stmt = $db->prepare("
    SELECT r.*, s.nom AS service_nom, s.id AS service_id_val,
           h.id AS hopital_id_val, h.nom AS hopital_nom,
           u.telephone AS patient_telephone,
           p.id AS paiement_id, p.montant, p.statut AS paiement_statut
    FROM rendez_vous r
    JOIN services s ON s.id = r.service_id
    JOIN hopitaux h ON h.id = s.hopital_id
    JOIN utilisateurs u ON u.id = r.patient_id
    LEFT JOIN paiements p ON p.rdv_id = r.id AND p.statut = 'valide'
    WHERE r.id = ?
");
$stmt->execute([$body['rdv_id']]);
$rdv = $stmt->fetch(PDO::FETCH_ASSOC);

if (!$rdv) {
    repondre(['erreur' => 'Rendez-vous introuvable'], 404);
}

// je vérifie les droits
if ($userConnecte['role'] === 'patient' && $rdv['patient_id'] != $userConnecte['utilisateur_id']) {
    repondre(['erreur' => "Vous ne pouvez pas annuler le RDV d'un autre patient"], 403);
}

if (in_array($rdv['statut'], ['consomme', 'annule', 'expire'])) {
    repondre(['erreur' => 'Ce rendez-vous ne peut plus être annulé'], 409);
}

$annulePar = in_array($userConnecte['role'], ['gerant', 'admin_hopital']) ? 'hopital' : 'patient';

// ── remboursement ──
$remboursement = null;
if ($rdv['paiement_id']) {
    if ($annulePar === 'hopital') {
        $db->prepare("UPDATE paiements SET statut = 'rembourse', rembourse_at = NOW() WHERE id = ?")
           ->execute([$rdv['paiement_id']]);
        $remboursement = ['statut' => 'total', 'montant' => $rdv['montant']];
    } else {
        $heuresAvantRdv = (strtotime($rdv['date_rdv'] . ' ' . $rdv['heure_rdv']) - time()) / 3600;
        if ($heuresAvantRdv >= 24) {
            $db->prepare("UPDATE paiements SET statut = 'rembourse', rembourse_at = NOW() WHERE id = ?")
               ->execute([$rdv['paiement_id']]);
            $remboursement = ['statut' => 'total', 'montant' => $rdv['montant']];
        } else {
            $remboursement = ['statut' => 'aucun', 'montant' => 0, 'raison' => 'Annulation moins de 24h avant le RDV'];
        }
    }
}

// ── annulation du RDV ──
$db->prepare("
    UPDATE rendez_vous
    SET statut = 'annule', annule_par = ?, annule_at = NOW(), raison_annulation = ?
    WHERE id = ?
")->execute([$annulePar, $body['raison'] ?? null, $rdv['id']]);

// ── invalidation du ticket ──
$db->prepare("UPDATE tickets SET statut = 'expire' WHERE rdv_id = ?")
   ->execute([$rdv['id']]);

// ── notification annulation au patient (si hôpital qui annule) ──
if ($annulePar === 'hopital') {
    $message = "SEN RDV SANTÉ+ : Votre RDV du {$rdv['date_rdv']} à {$rdv['heure_rdv']} ({$rdv['service_nom']}) a été annulé par l'hôpital. Remboursement total en cours.";
    $db->prepare("
        INSERT INTO notifications (utilisateur_id, rdv_id, type, canal, message)
        VALUES (?, ?, 'annulation', 'sms', ?)
    ")->execute([$rdv['patient_id'], $rdv['id'], $message]);
}

// ── alertes : une place vient de se libérer → je notifie les patients en attente ──
$alertesPatients = $db->prepare("
    SELECT a.patient_id, u.push_token, u.telephone
    FROM alertes_disponibilite a
    JOIN utilisateurs u ON u.id = a.patient_id
    WHERE a.service_id = ? AND a.actif = 1
    ORDER BY a.created_at ASC
");
$alertesPatients->execute([$rdv['service_id_val']]);
$patients = $alertesPatients->fetchAll(PDO::FETCH_ASSOC);

$nbNotifie      = 0;
$expoPushTokens = [];

if (!empty($patients)) {
    $dateRdv  = $rdv['date_rdv'];
    $heureRdv = substr($rdv['heure_rdv'], 0, 5);
    $msgSms   = "SEN RDV SANTÉ+ : Place dispo le {$dateRdv} à {$heureRdv} ({$rdv['service_nom']} - {$rdv['hopital_nom']}). Connectez-vous vite !";

    foreach ($patients as $patient) {
        $db->prepare("
            INSERT INTO notifications (utilisateur_id, type, canal, message)
            VALUES (?, 'flash', 'sms', ?)
        ")->execute([$patient['patient_id'], $msgSms]);

        if (!empty($patient['push_token'])) {
            $expoPushTokens[] = [
                'to'    => $patient['push_token'],
                'title' => '🏥 Place disponible !',
                'body'  => "RDV le {$dateRdv} à {$heureRdv} — {$rdv['service_nom']}. Premier arrivé, premier servi !",
                'data'  => [
                    'type'       => 'flash',
                    'service_id' => (int)$rdv['service_id_val'],
                    'hopital_id' => (int)$rdv['hopital_id_val'], // ← navigation au tap
                    'date_rdv'   => $dateRdv,
                    'heure_rdv'  => $rdv['heure_rdv'],
                ],
                'sound'     => 'default',
                'priority'  => 'high',
                'channelId' => 'senrdv',
            ];
        }
        $nbNotifie++;
    }

    if (!empty($expoPushTokens)) {
        $lots = array_chunk($expoPushTokens, 100);
        foreach ($lots as $lot) {
            envoyerPushExpo($lot);
        }
    }

    $db->prepare("UPDATE alertes_disponibilite SET actif = 0 WHERE service_id = ? AND actif = 1")
       ->execute([$rdv['service_id_val']]);
}

// ── audit log ──
$db->prepare("
    INSERT INTO audit_log (utilisateur_id, action, table_cible, enregistrement_id, details)
    VALUES (?, 'annuler_rdv', 'rendez_vous', ?, ?)
")->execute([
    $userConnecte['utilisateur_id'],
    $rdv['id'],
    json_encode(['annule_par' => $annulePar, 'raison' => $body['raison'] ?? null, 'alertes_notifiees' => $nbNotifie])
]);

repondre([
    'succes'             => true,
    'message'            => 'Rendez-vous annulé avec succès',
    'annule_par'         => $annulePar,
    'remboursement'      => $remboursement,
    'alertes_notifiees'  => $nbNotifie,
]);

// ── fonction envoi push Expo ──
function envoyerPushExpo(array $messages): void {
    $ch = curl_init('https://exp.host/--/api/v2/push/send');
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
            'Accept: application/json',
        ],
        CURLOPT_POSTFIELDS     => json_encode($messages),
        CURLOPT_TIMEOUT        => 10,
    ]);
    $reponse = curl_exec($ch);
    $erreur  = curl_error($ch);
    curl_close($ch);

    if ($erreur) error_log("Expo push annulation erreur: $erreur");
    else         error_log("Expo push annulation réponse: $reponse");
}