<?php
ob_start();
ini_set('display_errors', 0);
error_reporting(0);

require_once __DIR__ . '/../../../config/db.php';

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

header('Content-Type: application/json');

try {

/* =========================
   JSON INPUT
========================= */
$input = json_decode(file_get_contents('php://input'), true);
if (!$input) {
    $input = $_POST;
}

$commande_id   = (int)($input['commande_id'] ?? 0);
$mode_paiement = trim($input['mode_paiement'] ?? '');
$montant_verse = (float)($input['montant_verse'] ?? 0);
$table_id      = $input['table_id'] ?? null;
$client_id     = $input['client_id'] ?? null;
$produits      = $input['produits'] ?? [];

if (!$commande_id || !$mode_paiement || empty($produits)) {
    throw new Exception("Données manquantes ou invalides");
}

if ($montant_verse <= 0) {
    throw new Exception("Veuillez saisir un montant valide");
}

/* =========================
   UTILISATEUR
========================= */
$utilisateur_id = $_SESSION['user']['id'] ?? null;
if (!$utilisateur_id) {
    throw new Exception("Utilisateur non authentifié");
}

/* =========================
   SESSION CAISSE
========================= */
$stmt = $conn->prepare("
    SELECT id, caisse_id
    FROM sessions_caisse
    WHERE utilisateur_id=? AND statut='ouverte'
    LIMIT 1
");
$stmt->execute([$utilisateur_id]);
$session = $stmt->fetch(PDO::FETCH_ASSOC);

if (!$session) {
    throw new Exception("Aucune session de caisse ouverte");
}

$session_caisse_id = (int)$session['id'];
$caisse_id         = (int)$session['caisse_id'];

/* =========================
   COMMANDE
========================= */
$stmt = $conn->prepare("
    SELECT *
    FROM commandes
    WHERE id=? AND statut='ouverte'
    FOR UPDATE
");
$stmt->execute([$commande_id]);
$commande = $stmt->fetch(PDO::FETCH_ASSOC);

if (!$commande) {
    throw new Exception("Commande invalide ou déjà clôturée");
}

/* =========================
   TABLE / CLIENT
========================= */
$table_id  = $table_id  ?? $commande['table_id']  ?? null;
$client_id = $client_id ?? $commande['client_id'] ?? null;

/* =========================
   MODE → TYPE CAISSE
========================= */
$mode = strtolower($mode_paiement);

switch ($mode) {
    case 'espèces':
        $type_caisse_code = 'ESPECES';
        break;
    case 'wave':
    case 'orange money':
        $type_caisse_code = 'MOBILE';
        break;
    case 'carte visa':
    case 'virement':
    case 'chèque':
        $type_caisse_code = 'BANQUE';
        break;
    default:
        throw new Exception("Mode de paiement inconnu : $mode_paiement");
}

/* =========================
   MODE PAIEMENT ID
========================= */
$stmt = $conn->prepare("SELECT id FROM modes_paiement WHERE libelle=? LIMIT 1");
$stmt->execute([$mode_paiement]);
$mode_paiement_id = (int)$stmt->fetchColumn();

if (!$mode_paiement_id) {
    throw new Exception("Mode de paiement invalide");
}

/* =========================
   CALCUL TOTAL
========================= */
$totalHT = 0;

foreach ($produits as $p) {
    $prod_id = $p['id'] ?? null;
    $qte     = $p['quantite'] ?? null;
    $prix    = $p['prix_vente'] ?? null;

    if (!$prod_id || !$qte || $qte <= 0) {
        throw new Exception("Données produit invalides");
    }

    $stmt = $conn->prepare("
        SELECT s.quantite, p.prix_vente
        FROM produits p
        JOIN stock_depot s ON s.produit_id = p.id
        WHERE p.id = ?
    ");
    $stmt->execute([$prod_id]);
    $prod = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$prod) {
        throw new Exception("Produit introuvable");
    }

    if ($prod['quantite'] < $qte) {
        throw new Exception("Stock insuffisant pour un produit");
    }

    $totalHT += $prod['prix_vente'] * $qte;
}

$taxe           = 0;
$totalTTC       = $totalHT + $taxe;
$reste_a_payer  = $totalTTC - $montant_verse;
$statut         = ($reste_a_payer <= 0) ? 'Payé' : 'Impayé';
$montant_a_enregistrer = min($montant_verse, $totalTTC);
$monnaie_rendue = max($montant_verse - $totalTTC, 0);

/* =========================
   TRANSACTION
========================= */
$conn->beginTransaction();

$numero = 'POS-' . date('Ymd-His');

/* ===== VENTE ===== */
$stmt = $conn->prepare("
    INSERT INTO ventes (
        numero, client_id, table_id, commande_id, date_vente,
        totalHT, taxe, totalTTC,
        montant_verse, reste_a_payer,
        type_vente, mode_paiement_id, statut,
        utilisateur_id, session_caisse_id, created_at
    )
    VALUES (?, ?, ?, ?, NOW(), ?, ?, ?, ?, ?, 'Comptant', ?, ?, ?, ?, NOW())
");

$stmt->execute([
    $numero,
    $client_id,
    $table_id,
    $commande_id,
    $totalHT,
    $taxe,
    $totalTTC,
    $montant_verse,
    $$monnaie_rendue,
    $mode_paiement_id,
    $statut,
    $utilisateur_id,
    $session_caisse_id
]);

$vente_id = $conn->lastInsertId();

/* ===== DETAILS + STOCK ===== */
foreach ($produits as $p) {
    $conn->prepare("
        INSERT INTO ventes_details (vente_id, produit_id, quantite, prix_unitaire)
        VALUES (?, ?, ?, ?)
    ")->execute([
        $vente_id,
        $p['id'],
        $p['quantite'],
        $p['prix_vente']
    ]);

    $conn->prepare("
        UPDATE stock_depot
        SET quantite = quantite - ?
        WHERE produit_id = ?
    ")->execute([
        $p['quantite'],
        $p['id']
    ]);
}

/* ===== CAISSE ===== */
if ($montant_a_enregistrer > 0) {

$stmt = $conn->prepare("
    SELECT ct.id
    FROM caisse_types ct
    JOIN types_caisse tc ON tc.id = ct.type_caisse_id
    WHERE ct.caisse_id = ? AND tc.code = ?
    LIMIT 1
");
$stmt->execute([$caisse_id, $type_caisse_code]);
$caisse_type_id = $stmt->fetchColumn();

if (!$caisse_type_id) {
    throw new Exception("Caisse incompatible avec le mode de paiement");
}

$conn->prepare("
    INSERT INTO operations_caisse
    (session_caisse_id, caisse_type_id, type_operation, montant,
     mode_paiement_id, reference_table, reference_id, utilisateur_id, date_operation)
    VALUES (?, ?, 'entree', ?, ?, 'ventes', ?, ?, NOW())
")->execute([
    $session_caisse_id,
    $caisse_type_id,
    $montant_a_enregistrer,
    $mode_paiement_id,
    $vente_id,
    $utilisateur_id
]);

$conn->prepare("
    UPDATE caisse_types
    SET solde_actuel = solde_actuel + ?
    WHERE id = ?
")->execute([
    $montant_a_enregistrer,
    $caisse_type_id
]);
$conn->prepare("
            UPDATE caisses c
            SET c.solde_actuel = (
                SELECT SUM(solde_actuel)
                FROM caisse_types
                WHERE caisse_id = c.id
            )
            WHERE c.id = ?
        ")->execute([$caisse_id]);
    
/* ===== COMMANDE ===== */
$conn->prepare("
    UPDATE commandes
    SET statut = 'payee'
    WHERE id = ?
")->execute([$commande_id]);

/* ===== TABLE ===== */
if ($table_id) {
    $conn->prepare("
        UPDATE tables_restaurant
        SET statut = 'Libre'
        WHERE id = ?
    ")->execute([$table_id]);
 }
} 

unset($_SESSION['commande_en_cours']);
$conn->commit();

ob_clean();
echo json_encode([
    'success'  => true,
    'vente_id'=> $vente_id
]);
exit;

} catch (Throwable $e) {

    if ($conn->inTransaction()) {
        $conn->rollBack();
    }

    ob_clean();
    echo json_encode([
        'success' => false,
        'message' => $e->getMessage()
    ]);
    exit;
}
