<?php
//declare(strict_types=1);

session_start();
require_once __DIR__ . "/../../config/db.php";
require_once __DIR__ . "/../../includes/check_auth.php";

/* =========================================================
   SÉCURITÉ SESSION UTILISATEUR
========================================================= */

$utilisateur_id = $_SESSION['user']['id'] ?? 0;
if ($utilisateur_id <= 0) {
    throw new Exception("Utilisateur non authentifié");
}

/* =========================================================
   SESSION CAISSE OBLIGATOIRE
========================================================= */

$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 = $session['id'];
$caisse_id = $session['caisse_id'];

/* =========================================================
   POST
========================================================= */

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    die("Méthode invalide");
}

$reception_id     = (int)($_POST['reception_id'] ?? 0);
$mode_paiement_id = (int)($_POST['mode_paiement_id'] ?? 0);
$montant_verse    = (float)($_POST['montant_verse'] ?? 0);

if ($reception_id <= 0 || $mode_paiement_id <= 0) {
    die("Données invalides");
}

try {

    $conn->beginTransaction();

    /* =========================================================
       VERROUILLAGE RÉCEPTION
    ========================================================= */

    $stmt = $conn->prepare("
        SELECT rf.*, cf.fournisseur_id
        FROM receptions_fournisseurs rf
        JOIN commandes_fournisseurs cf ON cf.id = rf.commande_id
        WHERE rf.id = ?
        FOR UPDATE
    ");
    $stmt->execute([$reception_id]);
    $reception = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$reception) {
        throw new Exception("Réception introuvable");
    }

    /* Anti double achat */
    $check = $conn->prepare("SELECT COUNT(*) FROM achats WHERE reception_id=?");
    $check->execute([$reception_id]);
    if ($check->fetchColumn() > 0) {
        throw new Exception("Un achat existe déjà pour cette réception");
    }

    /* =========================================================
       DÉTAILS RÉCEPTION
    ========================================================= */

    $stmt = $conn->prepare("
        SELECT *
        FROM receptions_fournisseurs_details
        WHERE reception_id = ?
    ");
    $stmt->execute([$reception_id]);
    $details = $stmt->fetchAll(PDO::FETCH_ASSOC);

    if (!$details) {
        throw new Exception("Aucun produit trouvé");
    }

    /* =========================================================
       CALCUL TOTAL
    ========================================================= */

    $totalHT = 0;
    foreach ($details as $d) {
        $totalHT += $d['quantite_livree'] * $d['prix_achat'];
    }

    $taxe = 0;
    $remise = 0;
    $totalTTC = $totalHT + $taxe - $remise;
    $reste_a_payer = $totalTTC - $montant_verse;
    $statut = ($reste_a_payer <= 0) ? "Payé" : "Impayé";

    /* =========================================================
       GÉNÉRATION NUMÉRO BC
    ========================================================= */

    $annee = date("Y");
    $mois  = date("m");
    $sql = "SELECT COUNT(*) as nb 
            FROM achats 
            WHERE YEAR(date_achat) = :annee AND MONTH(date_achat) = :mois";
    $stmt = $conn->prepare($sql);
    $stmt->execute([
        ':annee' => $annee,
        ':mois'  => $mois
    ]);
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    $ordre = str_pad($row['nb'] + 1, 2, "0", STR_PAD_LEFT);
    $numero = "BC-" . $annee . "/" . $mois . "-" . $ordre;

    /* =========================================================
       INSERT ACHAT
    ========================================================= */

    $stmt = $conn->prepare("
        INSERT INTO achats
        (numero, reception_id, fournisseur_id, date_achat,
         totalHT, taxe, remise, totalTTC,
         montant_verse, reste_a_payer,
         type_achat, mode_paiement_id,
         statut, utilisateur_id, created_at)
        VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?, ?, NOW())
    ");
    $stmt->execute([
        $numero,
        $reception_id,
        $reception['fournisseur_id'],
        date("Y-m-d H:i:s"),
        $totalHT,
        $taxe,
        $remise,
        $totalTTC,
        $montant_verse,
        $reste_a_payer,
        "Réception",
        $mode_paiement_id,
        $statut,
        $utilisateur_id
    ]);

    $achat_id = $conn->lastInsertId();

    /* =========================================================
       DÉTAILS ACHAT
    ========================================================= */

    foreach ($details as $d) {

    $quantite = (int)$d['quantite_livree'];
    $prix     = (float)$d['prix_achat'];
    $depot_id = (int)$reception['depot_id'];

    if ($quantite <= 0) {
        throw new Exception("Quantité livrée invalide");
    }

    $stmt = $conn->prepare("
        INSERT INTO achats_details
        (achat_id, produit_id, quantite, prix_unitaire, depot_id)
        VALUES (?, ?, ?, ?, ?)
    ");

    $stmt->execute([
        $achat_id,
        $d['produit_id'],
        $quantite,
        $prix,
        $depot_id
    ]);

    /* Mouvement stock */
        /* $conn->prepare("
            INSERT INTO mouvements_stock
            (produit_id, depot_dest_id, quantite, type,
             reference_table, reference_id,
             utilisateur_id, date_mouvement)
            VALUES (?, ?, ?, 'achat', 'achats', ?, ?, NOW())
        ")->execute([
            $d['produit_id'],
            $reception['depot_id'],
            $quantite,
            $achat_id,
            $utilisateur_id
        ]); */
    }

    /* =========================================================
       DETTE FOURNISSEUR
    ========================================================= */

    $conn->prepare("
        INSERT INTO dettes_fournisseurs
        (achat_id, fournisseur_id, montant_total,
         montant_paye, reste_a_payer, statut, date_creation)
        VALUES (?, ?, ?, ?, ?, ?, NOW())
    ")->execute([
        $achat_id,
        $reception['fournisseur_id'],
        $totalTTC,
        $montant_verse,
        $reste_a_payer,
        ($reste_a_payer > 0 ? "En cours" : "Soldé")
    ]);

    /* =========================================================
       OPÉRATION CAISSE
    ========================================================= */

    if ($montant_verse > 0) {

        // ENREGISTRER HISTORIQUE PAIEMENT
        $conn->prepare("
            INSERT INTO paiements_fournisseurs
            (achat_id, fournisseur_id, montant,
            mode_paiement_id, date_paiement,
            utilisateur_id, entreprise_id, created_at)
            VALUES (?, ?, ?, ?, NOW(), ?, 1, NOW())
        ")->execute([
            $achat_id,
            $reception['fournisseur_id'], // ou $fournisseur_id dans ajouter
            $montant_verse,
            $mode_paiement_id,
            $utilisateur_id
        ]);

       


        $stmt = $conn->prepare("
            SELECT ct.id AS caisse_type_id
            FROM sessions_caisse sc
            JOIN caisse_types ct ON ct.caisse_id = sc.caisse_id
            JOIN types_caisse tc ON tc.id = ct.type_caisse_id
            JOIN modes_paiement mp ON mp.code = tc.code
            WHERE sc.id = ?
            AND mp.id = ?
        ");
        $stmt->execute([$session_caisse_id, $mode_paiement_id]);
        $caisseType = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$caisseType) {
            throw new Exception("Mode paiement non autorisé");
        }

        $caisse_type_id = $caisseType['caisse_type_id'];

         /* =========================================================
        CONTRÔLE SOLDE AVANT SORTIE
        ========================================================= */

        $stmt = $conn->prepare("
            SELECT solde_actuel
            FROM caisse_types
            WHERE id = ?
            FOR UPDATE
        ");
        $stmt->execute([$caisse_type_id]);
        $soldeData = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$soldeData) {
            throw new Exception("Caisse introuvable");
        }

        $solde_actuel = (float)$soldeData['solde_actuel'];

        if ($montant_verse > $solde_actuel) {
            throw new Exception(
                "Solde insuffisant. Disponible : " .
                number_format($solde_actuel, 0, '', ' ') . " FCFA"
            );
        }

        /* Opération */
        $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 (?, ?, 'sortie', ?, ?, 'achats', ?, ?, NOW())
        ")->execute([
            $session_caisse_id,
            $caisse_type_id,
            $montant_verse,
            $mode_paiement_id,
            $achat_id,
            $utilisateur_id
        ]);

        /* Mise à jour solde type */
        $conn->prepare("
            UPDATE caisse_types
            SET solde_actuel = solde_actuel - ?
            WHERE id = ?
        ")->execute([$montant_verse, $caisse_type_id]);

        /* Mise à jour solde global */
        $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]);
    }

    $conn->commit();

} catch (Exception $e) {

    $conn->rollBack();
    die("Erreur : " . $e->getMessage());
}

header("Location: /eagle_client_istanbulcups/index.php?page=factures_fournisseurs");
exit;
