<?php
include 'bd/myData.php';
require_once 'auth.php';
include 'cors.php';
setupCORS();

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    http_response_code(204);
    exit();
}

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

if ($_SERVER['REQUEST_METHOD'] == 'GET') {
    if (isset($_GET['id_achat'])) {
        $query = "SELECT dv.*,p.id_produit, p.designation 
                 FROM details_achats dv
                 LEFT JOIN produits p ON dv.id_produit = p.id_produit
                 WHERE dv.id_achat = :id_achat";
        $params = array(':id_achat' => $_GET['id_achat']);
        $result = metodGet($query, $params);
        $data = $result->fetchAll(PDO::FETCH_ASSOC);
        http_response_code(200);
        echo json_encode($data);
        exit();
    } else {
        $query = "SELECT * FROM details_achats";
        $result = metodGet($query);
        http_response_code(200);
        echo json_encode($result->fetchAll());
        exit();
    }
}

function updatePaymentPlanTotal($id_achat, $new_total)
{
    try {
        error_log("Starting updatePaymentPlanTotal for achat ID: $id_achat with new total: $new_total");

        // Check if payment plan exists
        $checkQuery = "SELECT id_paiement_tranche, montant_total, montant_par_tranche 
                      FROM paiements_fournisseurs_tranches 
                      WHERE id_achat = :id_achat";
        $result = metodGet($checkQuery, array(':id_achat' => $id_achat));
        $paymentPlan = $result->fetch(PDO::FETCH_ASSOC);

        if ($paymentPlan) {
            error_log("Found payment plan. Current montant_total: " . $paymentPlan['montant_total']);

            // Only update the montant_total, keep montant_par_tranche unchanged
            $updateQuery = "UPDATE paiements_fournisseurs_tranches 
                          SET montant_total = :new_total,
                              date_upd = CURRENT_TIMESTAMP,
                              user_upd = 'SYSTEM'
                          WHERE id_achat = :id_achat";

            $params = array(
                ':new_total' => $new_total,
                ':id_achat' => $id_achat
            );

            metodPut($updateQuery, $params, 'paiements_fournisseurs_tranches');
            error_log("Successfully updated payment plan total");

            return true;
        }
        error_log("No payment plan found for achat ID: $id_achat");
        return false;
    } catch (Exception $e) {
        error_log("Error in updatePaymentPlanTotal: " . $e->getMessage());
        // Don't throw the exception, just return false
        return false;
    }
}

// Update the updatePurchaseTotal function
function updatePurchaseTotal($id_achat)
{
    try {
        error_log("Starting updatePurchaseTotal for achat ID: $id_achat");

        // Calculate new total
        $query = "SELECT COALESCE(SUM(montant_total), 0) as new_total 
                 FROM details_achats 
                 WHERE id_achat = :id_achat";

        $result = metodGet($query, array(':id_achat' => $id_achat));
        $data = $result->fetch(PDO::FETCH_ASSOC);
        $newTotal = $data['new_total'];

        error_log("Calculated new total: $newTotal");

        // Update achats table
        $updateQuery = "UPDATE achats 
                       SET montant_total = :new_total,
                           date_upd = CURRENT_TIMESTAMP,
                           user_upd = 'SYSTEM'
                       WHERE id_achat = :id_achat";

        $params = array(
            ':new_total' => $newTotal,
            ':id_achat' => $id_achat
        );

        metodPut($updateQuery, $params, 'achats');
        error_log("Successfully updated achats total");

        // Try to update payment plan, but don't fail if it doesn't exist
        updatePaymentPlanTotal($id_achat, $newTotal);

        return $newTotal;
    } catch (Exception $e) {
        error_log("Error in updatePurchaseTotal: " . $e->getMessage());
        throw $e;
    }
}

function checkAndUpdateStock($id_produit, $quantite, $operation = 'increase')
{
    try {
        $queryCheck = "SELECT stock_actuel FROM produits WHERE id_produit = :id_produit";
        $resultCheck = metodGet($queryCheck, array(':id_produit' => $id_produit));
        $product = $resultCheck->fetch(PDO::FETCH_ASSOC);
        if (!$product) {
            throw new Exception("Product not found");
        }
        $currentStock = $product['stock_actuel'];

        $newStock = $operation === 'increase'
            ? $currentStock + $quantite
            : $currentStock - $quantite;

        $queryUpdate = "UPDATE produits 
                       SET stock_actuel = :new_stock,
                           date_upd = CURRENT_TIMESTAMP 
                       WHERE id_produit = :id_produit";

        $params = array(
            ':new_stock' => $newStock,
            ':id_produit' => $id_produit
        );
        metodPut($queryUpdate, $params, 'produits');
        return array(
            'success' => true,
            'new_stock' => $newStock,
            'is_low_stock' => $newStock === 0
        );
    } catch (Exception $e) {
        throw new Exception("Stock update failed: " . $e->getMessage());
    }
}


function logError($message, $data = null)
{
    error_log("DETAILS_ACHATS ERROR: " . $message);
    if ($data) {
        error_log("Data: " . print_r($data, true));
    }
}

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    try {
        $method = isset($_POST['METHOD']) ? $_POST['METHOD'] : 'POST';
        unset($_POST['METHOD']);

        logError("Request Method: " . $method);
        logError("POST Data: ", $_POST);
        logError("GET Data: ", $_GET);
        switch ($method) {
            case 'POST':
                if (
                    !isset($_POST['id_achat']) || !isset($_POST['id_produit']) ||
                    !isset($_POST['quantite']) || !isset($_POST['prix_achat_unitaire'])
                ) {
                    throw new Exception("Missing required fields");
                }

                // Check stock before proceeding - we increase stock when adding a purchase detail (buying from supplier)
                $stockResult = checkAndUpdateStock($_POST['id_produit'], $_POST['quantite'], 'increase');

                $montant_total = floatval($_POST['quantite']) * floatval($_POST['prix_achat_unitaire']);

                $query = "INSERT INTO details_achats(
                            id_achat, id_produit, quantite, prix_achat_unitaire,
                            montant_total, user_cre
                         ) VALUES (
                            :id_achat, :id_produit, :quantite, :prix_achat_unitaire,
                            :montant_total, :user_cre
                         )";

                $queryAutoIncrement = "SELECT MAX(id_detail_achat) as id_detail_achat FROM details_achats";

                $params = array(
                    ':id_achat' => $_POST['id_achat'],
                    ':id_produit' => $_POST['id_produit'],
                    ':quantite' => $_POST['quantite'],
                    ':prix_achat_unitaire' => $_POST['prix_achat_unitaire'],
                    ':montant_total' => $montant_total,
                    ':user_cre' => $_POST['user_cre'] ?? 'SYSTEM'
                );

                $result = metodPost($query, $queryAutoIncrement, $params, 'details_achats');
                $newTotal = updatePurchaseTotal($_POST['id_achat']);

                echo json_encode([
                    'success' => true,
                    'message' => 'Purchase detail created successfully',
                    'data' => array_merge($result, ['new_total' => $newTotal]),
                    'stock_info' => $stockResult
                ]);
                break;

            case 'PUT':
                if (!isset($_GET['id_detail_achat'])) {
                    throw new Exception("Detail ID is required for update");
                }

                try {
                    // Get current detail info
                    $getDetailQuery = "SELECT dv.id_achat, dv.id_produit, dv.quantite, dv.prix_achat_unitaire,
                                 pct.id_paiement_tranche, pct.montant_total as payment_total
                          FROM details_achats dv
                          LEFT JOIN achats v ON dv.id_achat = v.id_achat
                          LEFT JOIN paiements_fournisseurs_tranches pct ON v.id_achat = pct.id_achat
                          WHERE dv.id_detail_achat = :id_detail_achat";
                    $detailResult = metodGet($getDetailQuery, array(':id_detail_achat' => $_GET['id_detail_achat']));
                    $currentDetail = $detailResult->fetch(PDO::FETCH_ASSOC);

                    if (!$currentDetail) {
                        throw new Exception("Purchase detail not found");
                    }

                    // Calculate current and new amounts
                    $currentAmount = $currentDetail['quantite'] * $currentDetail['prix_achat_unitaire'];
                    $newAmount = floatval($_POST['quantite']) * floatval($_POST['prix_achat_unitaire']);

                    error_log("Current Amount: " . $currentAmount);
                    error_log("New Amount: " . $newAmount);

                    // Handle stock update
                    $quantityDifference = floatval($_POST['quantite']) - $currentDetail['quantite'];
                    if ($quantityDifference != 0) {
                        $operation = $quantityDifference < 0 ? 'decrease' : 'increase';
                        $stockResult = checkAndUpdateStock(
                            $_POST['id_produit'],
                            abs($quantityDifference),
                            $operation
                        );
                        error_log("Stock update result: " . json_encode($stockResult));
                    }

                    // If the new amount is less than current, we need to handle refund
                    if ($newAmount < $currentAmount && $currentDetail['id_paiement_tranche']) {
                        $refundAmount = $currentAmount - $newAmount;
                        error_log("Refund needed: " . $refundAmount);

                        // Get pending payments
                        $pendingQuery = "SELECT id_reglement, montant, date_echeance
                           FROM reglements_tranches_fournisseurs
                           WHERE id_paiement_tranche = :id_paiement_tranche
                           AND statut_reglements = 'En attente'
                           ORDER BY date_echeance ASC";
                        $pendingResult = metodGet($pendingQuery, array(':id_paiement_tranche' => $currentDetail['id_paiement_tranche']));
                        $pendingPayments = $pendingResult->fetchAll(PDO::FETCH_ASSOC);

                        $totalPending = array_reduce($pendingPayments, function ($sum, $payment) {
                            return $sum + floatval($payment['montant']);
                        }, 0);

                        error_log("Total pending payments: " . $totalPending);

                        if ($refundAmount <= $totalPending) {
                            // Handle by cancelling or reducing pending payments
                            $remainingRefund = $refundAmount;
                            foreach ($pendingPayments as $payment) {
                                if ($remainingRefund <= 0)
                                    break;

                                if ($remainingRefund >= $payment['montant']) {
                                    // Delete this payment
                                    $deleteQuery = "DELETE FROM reglements_tranches_fournisseurs WHERE id_reglement = :id_reglement";
                                    metodDelete($deleteQuery, array(':id_reglement' => $payment['id_reglement']), 'reglements_tranches_fournisseurs');
                                    $remainingRefund -= $payment['montant'];
                                } else {
                                    // Reduce this payment
                                    $newPaymentAmount = $payment['montant'] - $remainingRefund;
                                    $updateQuery = "UPDATE reglements_tranches_fournisseurs 
                                      SET montant = :new_amount,
                                          user_upd = :user_upd,
                                          date_upd = CURRENT_TIMESTAMP
                                      WHERE id_reglement = :id_reglement";
                                    metodPut($updateQuery, array(
                                        ':new_amount' => $newPaymentAmount,
                                        ':user_upd' => $_POST['user_upd'] ?? 'SYSTEM',
                                        ':id_reglement' => $payment['id_reglement']
                                    ), 'reglements_tranches_fournisseurs');
                                    $remainingRefund = 0;
                                }
                            }
                        } else {
                            // Delete all pending payments and create refund record
                            if (!empty($pendingPayments)) {
                                $deleteQuery = "DELETE FROM reglements_tranches_fournisseurs 
                                  WHERE id_paiement_tranche = :id_paiement_tranche 
                                  AND statut_reglements = 'En attente'";
                                metodDelete(
                                    $deleteQuery,
                                    array(':id_paiement_tranche' => $currentDetail['id_paiement_tranche']),
                                    'reglements_tranches_fournisseurs'
                                );
                            }

                            // Create refund record for remaining amount
                            $actualRefundAmount = $refundAmount - $totalPending;
                            $refundQuery = "INSERT INTO refund_fournisseur (
                    id_achat, id_paiement_tranche, montant_refund, motif,
                    statut_refund, date_refund, user_cre
                ) VALUES (
                    :id_achat, :id_paiement_tranche, :montant_refund, 
                    'Modification achat', 'En attente', CURRENT_DATE, :user_cre
                )";

                            $params = array(
                                ':id_achat' => $currentDetail['id_achat'],
                                ':id_paiement_tranche' => $currentDetail['id_paiement_tranche'],
                                ':montant_refund' => $actualRefundAmount,
                                ':user_cre' => $_POST['user_upd'] ?? 'SYSTEM'
                            );

                            metodPost(
                                $refundQuery,
                                "SELECT MAX(id_refund) as id FROM refund_fournisseur",
                                $params,
                                'refund_fournisseur'
                            );
                        }
                    }

                    // Update the detail itself
                    $updateQuery = "UPDATE details_achats 
                       SET id_produit = :id_produit,
                           quantite = :quantite,
                           prix_achat_unitaire = :prix_achat_unitaire,
                           montant_total = :montant_total,
                           user_upd = :user_upd,
                           date_upd = CURRENT_TIMESTAMP
                       WHERE id_detail_achat = :id_detail_achat";

                    $params = array(
                        ':id_detail_achat' => $_GET['id_detail_achat'],
                        ':id_produit' => $_POST['id_produit'],
                        ':quantite' => $_POST['quantite'],
                        ':prix_achat_unitaire' => $_POST['prix_achat_unitaire'],
                        ':montant_total' => $newAmount,
                        ':user_upd' => $_POST['user_upd'] ?? 'SYSTEM'
                    );

                    metodPut($updateQuery, $params, 'details_achats');

                    // Update purchase total
                    $newTotal = updatePurchaseTotal($currentDetail['id_achat']);

                    echo json_encode([
                        'success' => true,
                        'message' => 'Purchase detail updated successfully',
                        'data' => array_merge(['new_total' => $newTotal], $params),
                        'stock_info' => $stockResult ?? null
                    ]);
                    exit();

                } catch (Exception $e) {
                    error_log("Error in PUT operation: " . $e->getMessage());
                    http_response_code(500);
                    echo json_encode(['error' => $e->getMessage()]);
                    exit();
                }
                break;
                if (!isset($_GET['id_detail_achat'])) {
                    throw new Exception("Detail ID is required for update");
                }

                try {
                    // Get current detail info
                    $currentDetail = getCurrentDetailInfo($_GET['id_detail_achat']);

                    // Validate required fields
                    if (!isset($_POST['id_produit']) || !isset($_POST['quantite']) || !isset($_POST['prix_achat_unitaire'])) {
                        throw new Exception("Missing required fields");
                    }

                    // Handle stock update
                    $quantite = floatval($_POST['quantite']);
                    $stockDifference = $currentDetail['quantite'] - $quantite;

                    if ($stockDifference < 0) {
                        $stockResult = checkAndUpdateStock($_POST['id_produit'], abs($stockDifference), 'increase');
                    } else if ($stockDifference > 0) {
                        $stockResult = checkAndUpdateStock($_POST['id_produit'], abs($stockDifference), 'decrease');
                    }

                    // Calculate new total after update
                    $newTotal = calculateNewTotal($currentDetail['id_achat'], $_POST, $currentDetail);
                    $currentTotal = floatval($currentDetail['montant_total']);

                    // If refund needed
                    if ($newTotal < $currentTotal) {
                        $refundAmount = $currentTotal - $newTotal;
                        $refundResult = handleRefundScenarios(
                            $currentDetail['id_achat'],
                            $refundAmount,
                            isset($_POST['user_upd']) ? $_POST['user_upd'] : 'SYSTEM'
                        );

                        // Process result based on scenario
                        switch ($refundResult['scenario']) {
                            case 1:
                            case 2:
                                // Just update the purchase detail as payments are handled
                                updatePurchaseDetail($_GET['id_detail_achat'], $_POST);
                                break;

                            case 3:
                                // Update purchase detail and handle refund process
                                updatePurchaseDetail($_GET['id_detail_achat'], $_POST);
                                break;
                        }

                        // Update the total purchase amount
                        updatePurchaseTotal($currentDetail['id_achat']);

                        echo json_encode([
                            'success' => true,
                            'message' => 'Purchase detail updated and refund processed',
                            'refund_info' => $refundResult,
                            'stock_info' => $stockResult ?? null
                        ]);

                    } else {
                        // Regular update without refund
                        updatePurchaseDetail($_GET['id_detail_achat'], $_POST);
                        updatePurchaseTotal($currentDetail['id_achat']);

                        echo json_encode([
                            'success' => true,
                            'message' => 'Purchase detail updated successfully',
                            'stock_info' => $stockResult ?? null
                        ]);
                    }

                } catch (Exception $e) {
                    error_log("Error in PUT operation: " . $e->getMessage());
                    http_response_code(500);
                    echo json_encode(['error' => $e->getMessage()]);
                }
                exit();
                break;

            case 'DELETE':
                $id = $_GET['id_detail_achat'];


                $getDetailQuery = "SELECT id_achat, id_produit, quantite FROM details_achats WHERE id_detail_achat = :id_detail_achat";
                $detailResult = metodGet($getDetailQuery, array(':id_detail_achat' => $id));
                $detailData = $detailResult->fetch(PDO::FETCH_ASSOC);

                if ($detailData) {

                    checkAndUpdateStock($detailData['id_produit'], $detailData['quantite'], 'decrease');

                    $query = "DELETE FROM details_achats WHERE id_detail_achat = :id";
                    $params = array(':id' => $id);
                    $result = metodDelete($query, $params, 'details_achats');

                    updatePurchaseTotal($detailData['id_achat']);
                }

                http_response_code(200);
                echo json_encode([
                    'success' => true,
                    'message' => 'Purchase detail deleted successfully',
                    'data' => $result
                ]);
                break;
        }
        exit();
    } catch (Exception $e) {
        http_response_code(500);
        echo json_encode(['error' => $e->getMessage()]);
        exit();
    }
}
