<?php
// ============================================
// SEN RDV SANTÉ+ — Créer un rendez-vous
// POST /api/rdv/creer.php
// ============================================
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();
if ($userConnecte['role'] !== 'patient') {
    repondre(['erreur' => 'Seuls les patients peuvent créer un rendez-vous'], 403);
}

$db   = getDB();
$body = getBody();

validerChamps($body, ['service_id', 'date_rdv', 'patient_nom', 'patient_prenom', 'motif']);

$prixReservation = (float) getParametre('prix_reservation', 200);

$creneauId = null;
if (!empty($body['creneau_id'])) {
    $raw       = $body['creneau_id'];
    $creneauId = is_numeric($raw) ? intval($raw) : null;
}

// ── je récupère le service avec son mode ──
$stmt = $db->prepare("
    SELECT id, nom, quota_rdv_jour, hopital_id, mode_rdv, quota_journalier
    FROM services WHERE id = ? AND actif = 1
");
$stmt->execute([$body['service_id']]);
$service = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$service) {
    repondre(['erreur' => 'Service introuvable'], 404);
}

// ── je détecte le mode depuis la plage ouverte ce jour (priorité sur services.mode_rdv) ──
$stmtMode = $db->prepare("
    SELECT mode_rdv FROM plages_ouvertes
    WHERE service_id = ? AND date_plage = ? AND actif = 1
    LIMIT 1
");
$stmtMode->execute([$body['service_id'], $body['date_rdv']]);
$plageMode = $stmtMode->fetch(PDO::FETCH_ASSOC);
$modeRdv   = $plageMode ? ($plageMode['mode_rdv'] ?? 'creneaux') : ($service['mode_rdv'] ?? 'creneaux');

// ── vérification selon le mode ──
if ($modeRdv === 'creneaux') {
    if (empty($body['heure_rdv'])) {
        repondre(['erreur' => 'heure_rdv obligatoire pour ce service'], 422);
    }

    // quota journalier non atteint
    $stmt = $db->prepare("
        SELECT COUNT(*) AS pris FROM rendez_vous
        WHERE service_id = ? AND date_rdv = ?
        AND statut NOT IN ('annule', 'expire')
    ");
    $stmt->execute([$body['service_id'], $body['date_rdv']]);
    if ($stmt->fetch(PDO::FETCH_ASSOC)['pris'] >= $service['quota_rdv_jour']) {
        repondre(['erreur' => 'Plus de places disponibles pour ce service ce jour-là'], 409);
    }

    // ✅ doublon : même patient (nom+prénom), même service, même date, même heure
    $stmt = $db->prepare("
        SELECT id FROM rendez_vous
        WHERE service_id      = ?
          AND date_rdv        = ?
          AND heure_rdv       = ?
          AND patient_nom     = ?
          AND patient_prenom  = ?
          AND statut NOT IN ('annule', 'expire')
    ");
    $stmt->execute([
        $body['service_id'],
        $body['date_rdv'],
        $body['heure_rdv'],
        trim($body['patient_nom']),
        trim($body['patient_prenom']),
    ]);
    if ($stmt->fetch()) {
        repondre(['erreur' => 'Un rendez-vous existe déjà pour ce patient à ce créneau'], 409);
    }

} else {
    // Mode quota
    $stmtPlageQ = $db->prepare("
        SELECT id, heure_debut, heure_fin, quota FROM plages_ouvertes
        WHERE service_id = ? AND date_plage = ?
          AND mode_rdv = 'quota' AND actif = 1
        LIMIT 1
    ");
    $stmtPlageQ->execute([$body['service_id'], $body['date_rdv']]);
    $plageQuota = $stmtPlageQ->fetch(PDO::FETCH_ASSOC);

    if (!$plageQuota) {
        repondre(['erreur' => 'Aucune plage ouverte pour ce jour'], 409);
    }

    $quota = (int)($plageQuota['quota'] ?: $service['quota_journalier'] ?: 10);

    $stmtPris = $db->prepare("
        SELECT COUNT(*) AS pris FROM rendez_vous
        WHERE service_id = ? AND date_rdv = ?
        AND statut NOT IN ('annule', 'expire')
    ");
    $stmtPris->execute([$body['service_id'], $body['date_rdv']]);
    $pris = (int)$stmtPris->fetch()['pris'];

    if ($pris >= $quota) {
        repondre(['erreur' => 'Le quota de patients pour ce jour est atteint'], 409);
    }

    // ✅ doublon mode quota : même patient (nom+prénom), même service, même date
    $stmt = $db->prepare("
        SELECT id FROM rendez_vous
        WHERE service_id     = ?
          AND date_rdv       = ?
          AND patient_nom    = ?
          AND patient_prenom = ?
          AND statut NOT IN ('annule', 'expire')
    ");
    $stmt->execute([
        $body['service_id'],
        $body['date_rdv'],
        trim($body['patient_nom']),
        trim($body['patient_prenom']),
    ]);
    if ($stmt->fetch()) {
        repondre(['erreur' => 'Un rendez-vous existe déjà pour ce patient ce jour-là'], 409);
    }

    // en mode quota, heure = heure de début de la plage
    $body['heure_rdv'] = $plageQuota['heure_debut'];
}

// ── vérification plage ouverte (mode créneaux) ──
$plageOuverte = null;
if ($modeRdv === 'creneaux') {
    $stmtPlage = $db->prepare("
        SELECT id FROM plages_ouvertes
        WHERE service_id = ? AND date_plage = ?
          AND heure_debut <= ? AND heure_fin >= ?
          AND actif = 1
        LIMIT 1
    ");
    $stmtPlage->execute([
        $body['service_id'], $body['date_rdv'],
        $body['heure_rdv'],  $body['heure_rdv'],
    ]);
    $plageOuverte = $stmtPlage->fetch(PDO::FETCH_ASSOC);
}

$statutInitial = ($plageOuverte || $modeRdv === 'quota') ? 'confirme' : 'en_attente';

// ── calcul du numéro de file ──
if ($modeRdv === 'creneaux') {
    // Mode créneaux : numéro basé sur l'ordre chronologique des heures
    // Nombre de RDV avant cette heure (créneaux précédents)
    $stmtAvant = $db->prepare("
        SELECT COUNT(*) AS nb
        FROM rendez_vous
        WHERE service_id = ?
          AND date_rdv = ?
          AND heure_rdv < ?
          AND statut NOT IN ('annule', 'expire')
    ");
    $stmtAvant->execute([$body['service_id'], $body['date_rdv'], $body['heure_rdv']]);
    $nbAvant = (int)$stmtAvant->fetch(PDO::FETCH_ASSOC)['nb'];

    // Position dans ce créneau (même heure, inscrits avant)
    $stmtMemeHeure = $db->prepare("
        SELECT COUNT(*) AS nb
        FROM rendez_vous
        WHERE service_id = ?
          AND date_rdv = ?
          AND heure_rdv = ?
          AND statut NOT IN ('annule', 'expire')
    ");
    $stmtMemeHeure->execute([$body['service_id'], $body['date_rdv'], $body['heure_rdv']]);
    $nbMemeHeure = (int)$stmtMemeHeure->fetch(PDO::FETCH_ASSOC)['nb'];

    $numeroFile = $nbAvant + $nbMemeHeure + 1;
} else {
    // Mode quota : numéro simple (ordre d'inscription)
    $stmtFile = $db->prepare("
        SELECT COUNT(*) + 1 AS prochain_numero
        FROM rendez_vous
        WHERE service_id = ? AND date_rdv = ?
        AND statut NOT IN ('annule', 'expire')
    ");
    $stmtFile->execute([$body['service_id'], $body['date_rdv']]);
    $numeroFile = (int)$stmtFile->fetch(PDO::FETCH_ASSOC)['prochain_numero'];
}

// ── création du RDV ──
$stmt = $db->prepare("
    INSERT INTO rendez_vous
        (patient_id, service_id, creneau_id, patient_nom, patient_prenom,
         patient_age, motif, date_rdv, heure_rdv, statut, numero_file)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
");
$stmt->execute([
    $userConnecte['utilisateur_id'],
    $body['service_id'],
    $creneauId,
    trim($body['patient_nom']),
    trim($body['patient_prenom']),
    $body['patient_age'] ?? null,
    trim($body['motif']),
    $body['date_rdv'],
    $body['heure_rdv'],
    $statutInitial,
    $numeroFile,
]);
$rdvId = $db->lastInsertId();

// ── si confirmé auto : créer paiement + notif ──
if ($statutInitial === 'confirme') {
    $expireAt = date('Y-m-d H:i:s', strtotime('+3 hours'));
    $db->prepare("
        INSERT INTO paiements (rdv_id, montant, operateur, telephone_paiement, expire_at)
        VALUES (?, ?, 'wave', ?, ?)
    ")->execute([
        $rdvId, $prixReservation,
        $userConnecte['telephone'] ?? '', $expireAt,
    ]);

    $heure = substr($body['heure_rdv'], 0, 5);
    $msg   = $modeRdv === 'quota'
        ? "SEN RDV SANTE+ : Votre RDV du {$body['date_rdv']} est confirme — vous etes N°{$numeroFile} ({$service['nom']}). Payez {$prixReservation} FCFA via Mobile Money."
        : "SEN RDV SANTE+ : Votre RDV du {$body['date_rdv']} a {$heure} ({$service['nom']}) est confirme — N°{$numeroFile} dans la file. Payez {$prixReservation} FCFA via Mobile Money.";

    $db->prepare("
        INSERT INTO notifications (utilisateur_id, rdv_id, type, canal, message)
        VALUES (?, ?, 'confirmation', 'sms', ?)
    ")->execute([$userConnecte['utilisateur_id'], $rdvId, $msg]);

} else {
    $stmt = $db->prepare("
        INSERT INTO notifications (utilisateur_id, rdv_id, type, canal, message)
        SELECT u.id, ?, 'confirmation', 'push',
               CONCAT('Nouvelle demande RDV : ', ?, ' ', ?, ' le ', ?)
        FROM utilisateurs u
        JOIN gerant_services gs ON gs.gerant_id = u.id
        WHERE gs.service_id = ? AND u.role = 'gerant' AND u.actif = 1
    ");
    $stmt->execute([
        $rdvId,
        trim($body['patient_prenom']), trim($body['patient_nom']),
        $body['date_rdv'],
        $body['service_id'],
    ]);
}

repondre([
    'succes'  => true,
    'message' => $statutInitial === 'confirme'
        ? "RDV confirme ✅ — vous etes N°{$numeroFile} · Payez {$prixReservation} FCFA"
        : 'Demande envoyee, en attente de confirmation',
    'rdv' => [
        'id'            => $rdvId,
        'statut'        => $statutInitial,
        'confirme_auto' => $statutInitial === 'confirme',
        'mode_rdv'      => $modeRdv,
        'numero_file'   => $numeroFile,
        'service'       => $service['nom'],
        'date_rdv'      => $body['date_rdv'],
        'heure_rdv'     => $body['heure_rdv'],
        'patient_nom'   => trim($body['patient_nom']),
        'patient_prenom'=> trim($body['patient_prenom']),
        'montant'       => $prixReservation,
    ]
], 201);