<?php

namespace App\Controllers;

use App\Controllers\AdminController;
use App\Models\SortieCaisse;
use App\Models\Orders;
use App\Models\Recouvrement;
use App\Models\Stores;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Writer\Csv as CsvWriter;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\Alignment;

class SortieCaisseController extends AdminController
{
    public function __construct()
    {
        parent::__construct();
    }

    private $mapping = [
        // superadmin
        "Achat de matériel informatique"                  => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'SuperAdmin'
        ],
        "Achat équipement de sécurité"                    => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'SuperAdmin'
        ],
        "Achat mobilier de bureau"                        => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'SuperAdmin'
        ],
        "Paiement salaire des collaborateurs"             => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'SuperAdmin'
        ],
        "Cotisation sociales"                            => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'SuperAdmin'
        ],
        "Remboursement d'avance moto"                    => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'SuperAdmin'
        ],
        "Payement prime ou endemnité"                    => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'SuperAdmin'
        ],
        "Paiement sous-traitant"                         => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'SuperAdmin'
        ],
        "Frais de formation"                             => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'SuperAdmin'
        ],
        "Paiement loyer"                                 => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'SuperAdmin'
        ],
        "Frais de formation externe"                     => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'SuperAdmin'
        ],
        "Abonnement internet"                            => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'SuperAdmin'
        ],
        "Entretien locaux"                               => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'SuperAdmin'
        ],
        "Paiement fournisseur"                           => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'SuperAdmin'
        ],
        "Remboursement de frais"                         => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'SuperAdmin'
        ],
        "Paiement assurance"                             => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'SuperAdmin'
        ],
        "Réparation immobilisation"                      => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'SuperAdmin'
        ],
        "DVD"                                            => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'SuperAdmin'
        ],
        "Déclaration fiscale - Déclaration d'impôts"     => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'SuperAdmin'
        ],
        "Enregistrement des contrats de bail au centre fiscal" => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'SuperAdmin'
        ],
        // ----- Raisons Admin -----
        "Achat de matériel informatique"                  => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'Direction'
        ],
        "Achat équipement de sécurité"                    => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'Direction'
        ],
        "Achat mobilier de bureau"                        => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'Direction'
        ],
        "Paiement salaire des collaborateurs"             => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'Direction'
        ],
        "Cotisation sociales"                            => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'Direction'
        ],
        "Remboursement d'avance moto"                    => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'Direction'
        ],
        "Payement prime ou endemnité"                    => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'Direction'
        ],
        "Paiement sous-traitant"                         => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'Direction'
        ],
        "Frais de formation"                             => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'Direction'
        ],
        "Paiement loyer"                                 => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'Direction'
        ],
        "Frais de formation externe"                     => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'Direction'
        ],
        "Abonnement internet"                            => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'Direction'
        ],
        "Entretien locaux"                               => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'Direction'
        ],
        "Paiement fournisseur"                           => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'Direction'
        ],
        "Remboursement de frais"                         => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'Direction'
        ],
        "Paiement assurance"                             => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'Direction'
        ],
        "Réparation immobilisation"                      => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'Direction'
        ],
        "DVD"                                            => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'Direction'
        ],
        "Déclaration fiscale - Déclaration d'impôts"     => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'Direction'
        ],
        "Enregistrement des contrats de bail au centre fiscal" => [
            'source_fond'        => 'Budget Directionnel',
            'initiateur_demande' => 'Direction'
        ],

        // ----- Raisons Caissier -----
        "Achat materiel - Réparation immobilisation"      => [
            'source_fond'        => 'Caisse Courante',
            'initiateur_demande' => 'Caissière'
        ],
        "Réparation matériel"                            => [
            'source_fond'        => 'Caisse Courante',
            'initiateur_demande' => 'Caissière'
        ],
        "Maintenance équipement"                         => [
            'source_fond'        => 'Caisse Courante',
            'initiateur_demande' => 'Caissière'
        ],
        "Achats de Matériaux et Fournitures"             => [
            'source_fond'        => 'Caisse Courante',
            'initiateur_demande' => 'Caissière'
        ],
        "Achat produits de nettoyage"                    => [
            'source_fond'        => 'Caisse Courante',
            'initiateur_demande' => 'Caissière'
        ],
        "Achat consommable informatique"                 => [
            'source_fond'        => 'Caisse Courante',
            'initiateur_demande' => 'Caissière'
        ],
        "Achat petit outillage"                          => [
            'source_fond'        => 'Caisse Courante',
            'initiateur_demande' => 'Caissière'
        ],
        "Avance à un prestataire"                        => [
            'source_fond'        => 'Caisse Courante',
            'initiateur_demande' => 'Caissière'
        ],
        "Payement prestataire"                           => [
            'source_fond'        => 'Caisse Courante',
            'initiateur_demande' => 'Caissière'
        ],
        "Payement éléctricité"                           => [
            'source_fond'        => 'Caisse Courante',
            'initiateur_demande' => 'Caissière'
        ],
        "Frais de mission - Déplacement"                 => [
            'source_fond'        => 'Caisse Courante',
            'initiateur_demande' => 'Caissière'
        ],
        "Achat de carburant"                             => [
            'source_fond'        => 'Caisse Courante',
            'initiateur_demande' => 'Caissière'
        ],
        "Paiement transport marchandise"                 => [
            'source_fond'        => 'Caisse Courante',
            'initiateur_demande' => 'Caissière'
        ],
        "Achat pièces pour réparation moto"              => [
            'source_fond'        => 'Caisse Courante',
            'initiateur_demande' => 'Caissière'
        ],
    ];

    private $pageTitle = 'Décaissement';

    public function index()
    {
        $this->verifyRole('viewSortieCaisse');
        $admin_options = [
            "Achat de matériel informatique",
            "Achat équipement de sécurité",
            "Achat mobilier de bureau",
            "Paiement salaire des collaborateurs",
            "Cotisation sociales",
            "Remboursement d'avance moto",
            "Payement prime ou endemnité",
            "Paiement sous-traitant",
            "Frais de formation",
            "Paiement loyer",
            "Frais de formation externe",
            "Abonnement internet",
            "Entretien locaux",
            "Paiement fournisseur",
            "Remboursement de frais",
            "Paiement assurance",
            "Réparation immobilisation",
            "DVD",
            "Déclaration fiscale - Déclaration d'impôts",
            "Enregistrement des contrats de bail au centre fiscal"
        ];

        $caissier_options = [
            "Achat materiel - Réparation immobilisation",
            "Réparation matériel",
            "Maintenance équipement",
            "Achats de Matériaux et Fournitures",
            "Achat produits de nettoyage",
            "Achat consommable informatique",
            "Achat petit outillage",
            "Avance à un prestataire",
            "Payement prestataire",
            "Payement éléctricité",
            "Frais de mission - Déplacement",
            "Achat de carburant",
            "Paiement transport marchandise",
            "Achat pièces pour réparation moto"
        ];

        $Stores = new Stores();
        $stor = $Stores->getActiveStore();
        $data = json_decode($this->fetchTotal(),true);
        $data['admin_options'] = $admin_options;
        $data['caissier_options'] = $caissier_options;
        $data['stores'] = $stor;
        
        $this->render_template('sortieCaisse/index', $data);
    }

    // Create an AJAX endpoint to access the fetchTotal() function

    public function fetchTotal(){
        $data = [
            'user_permission' => $this->permission,
            'page_title' => $this->pageTitle
        ];
        return json_encode($data);
    }

    public function fetchSortieCaisseData()
    {
        helper(['url', 'form']);
        $SortieCaisse = new SortieCaisse();
    
        // Initialiser les variables pour DataTables
        $draw = intval($this->request->getVar('draw'));
    
        $data = $SortieCaisse->getAllSortieCaisse();
        $totalRecords = count($data);
    
        $session = session();
        $users = $session->get('user');
        
        // ✅ Vérifier si l'utilisateur est DAF ou Direction UNIQUEMENT
        $canManage = in_array($users['group_name'], ['Direction', 'DAF','SuperAdmin']);
        $isCaissiere = $users['group_name'] === 'Caissière';
        
        $result = [
            "draw"            => $draw,
            "recordsTotal"    => $totalRecords,
            "recordsFiltered" => $totalRecords,
            "data"            => []
        ];
    
        foreach ($data as $key => $value) {
            $buttons = '';
            
            // ✅ BOUTON MODIFICATION : Seulement pour DAF et Direction
            if (in_array('updateSortieCaisse', $this->permission) && $canManage) {
                $buttons .= '<button type="button" class="btn btn-default" onclick="editFunc(' . $value['id_sortie'] . ')" data-toggle="modal" data-target="#updateModal"><i class="fa fa-pencil"></i></button>';
            }
            
            // ✅ BOUTON VALIDATION : Seulement pour DAF et Direction
            if (in_array('validateSortieCaisse', $this->permission) && $canManage) {
                $buttons .= '<button type="button" class="btn btn-default" onclick="validateFunc(' . $value['id_sortie'] . ')"><i class="fa fa-check-circle"></i></button>';
            }
            
            // ✅ NOUVEAU : BOUTON "MARQUER COMME PAYÉ" pour Caissière
            if ($isCaissiere && $value['statut'] === 'Valider') {
                $buttons .= '<button type="button" class="btn btn-success btn-sm" onclick="markAsPaidFunc(' . $value['id_sortie'] . ')" title="Marquer comme payé"><i class="fa fa-money"></i> Payé</button>';
            }
            
            // Afficher un badge si déjà payé
            if ($value['statut'] === 'Payé') {
                $buttons .= '<span class="label label-success"><i class="fa fa-check"></i> Payé</span>';
            }
            
            // ✅ CORRECTION : Enlever 'admin_raison' pour les caissières
            if($users["group_name"] === "Caissière"){
                $result['data'][$key] = [
                    $value['id_sortie'],
                    number_format($value['montant_retire'], 0, '.', ' '),
                    $value['date_retrait'],
                    $value['sortie_personnel'],
                    $value['motif'],
                    $value['statut'],
                    $value['admin_raison'],
                    $buttons  // Les caissières ne verront PAS les boutons (car $canManage = false)
                ];
            }
            elseif ($users["group_name"] === "Direction" || $users["group_name"] === "DAF" ||$users["group_name"] === "SuperAdmin" ) {
                $result['data'][$key] = [
                    $value['id_sortie'],
                    number_format($value['montant_retire'], 0, '.', ' '),
                    $value['date_retrait'],
                    $value['sortie_personnel'],
                    $value['motif'],
                    $value['source_fond'],
                    $value['initiateur_demande'],
                    $this->returnStoreName($value['store_id']),
                    $value['commentaire'],
                    $value['statut'],
                    $buttons  // DAF et Direction verront les boutons
                ];
            }
            elseif ($users["group_name"] === "Conseil") {
                // ✅ Conseil peut voir les données mais SANS boutons d'action
                $result['data'][$key] = [
                    $value['id_sortie'],
                    number_format($value['montant_retire'], 0, '.', ' '),
                    $value['date_retrait'],
                    $value['sortie_personnel'],
                    $value['motif'],
                    $value['source_fond'],
                    $value['initiateur_demande'],
                    $this->returnStoreName($value['store_id']),
                    $value['commentaire'],
                    $value['statut'],
                    ''  // Pas de boutons pour Conseil
                ];
            }
        }
        return $this->response->setJSON($result);
    }
    
    /**
     * ✅ NOUVELLE MÉTHODE : Marquer un décaissement comme payé
     * Accessible uniquement par les caissières
     */
/**
 * ✅ CORRECTION COMPLÈTE : Marquer un décaissement comme payé
 * Accessible uniquement par les caissières
 */
public function markAsPaid($id_sortie)
{
    $session = session();
    $users = $session->get('user');
    
    if ($users['group_name'] !== 'Caissière') {
        return $this->response->setJSON([
            'success' => false,
            'messages' => 'Accès refusé. Seules les caissières peuvent marquer un décaissement comme payé.'
        ]);
    }

    try {
        $SortieCaisse = new SortieCaisse();
        
        // Récupérer le décaissement
        $decaissement = $SortieCaisse->getSortieCaisseSingle($id_sortie);
        
        if (!$decaissement) {
            return $this->response->setJSON([
                'success' => false,
                'messages' => 'Décaissement introuvable.'
            ]);
        }
        
        // Vérifier que le statut est "Valider"
        if ($decaissement['statut'] !== 'Valider') {
            return $this->response->setJSON([
                'success' => false,
                'messages' => 'Ce décaissement ne peut pas être marqué comme payé.<br>Statut actuel : ' . $decaissement['statut']
            ]);
        }
        
        // ✅ NOUVEAU: VÉRIFICATION DES FONDS DISPONIBLES
        $orders = new Orders();
        $Recouvrement = new Recouvrement();
        
        $paymentData = $orders->getPaymentModes();
        $totalRecouvrement = $Recouvrement->getTotalRecouvrements();
        $total_sortie_caisse = $SortieCaisse->getTotalSortieCaisse();

        // EXTRACTION DES TOTAUX (uniquement les décaissements déjà payés)
        $total_sortie_espece = 0;
        $total_sortie_mvola = 0;
        $total_sortie_virement = 0;
        
        if (is_object($total_sortie_caisse)) {
            $total_sortie_espece = isset($total_sortie_caisse->total_espece) ? (float) $total_sortie_caisse->total_espece : 0;
            $total_sortie_mvola = isset($total_sortie_caisse->total_mvola) ? (float) $total_sortie_caisse->total_mvola : 0;
            $total_sortie_virement = isset($total_sortie_caisse->total_virement) ? (float) $total_sortie_caisse->total_virement : 0;
        }

        // Recouvrements
        $total_recouvrement_me = 0;
        $total_recouvrement_be = 0;
        $total_recouvrement_bm = 0;
        $total_recouvrement_mb = 0;
        
        if (is_object($totalRecouvrement)) {
            $total_recouvrement_me = isset($totalRecouvrement->me) ? (float) $totalRecouvrement->me : 0;
            $total_recouvrement_be = isset($totalRecouvrement->be) ? (float) $totalRecouvrement->be : 0;
            $total_recouvrement_bm = isset($totalRecouvrement->bm) ? (float) $totalRecouvrement->bm : 0;
            $total_recouvrement_mb = isset($totalRecouvrement->mb) ? (float) $totalRecouvrement->mb : 0;
        }

        // Orders
        $total_espece1 = 0;
        $total_espece2 = 0;
        $total_mvola1 = 0;
        $total_mvola2 = 0;
        $total_virement1 = 0;
        $total_virement2 = 0;
        
        if (is_object($paymentData)) {
            $total_espece1 = isset($paymentData->total_espece1) ? (float) $paymentData->total_espece1 : 0;
            $total_espece2 = isset($paymentData->total_espece2) ? (float) $paymentData->total_espece2 : 0;
            $total_mvola1 = isset($paymentData->total_mvola1) ? (float) $paymentData->total_mvola1 : 0;
            $total_mvola2 = isset($paymentData->total_mvola2) ? (float) $paymentData->total_mvola2 : 0;
            $total_virement1 = isset($paymentData->total_virement_bancaire1) ? (float) $paymentData->total_virement_bancaire1 : 0;
            $total_virement2 = isset($paymentData->total_virement_bancaire2) ? (float) $paymentData->total_virement_bancaire2 : 0;
        }

        // CALCUL DES SOLDES DISPONIBLES
        $total_espece_disponible = $total_espece1 + 
                                   $total_espece2 + 
                                   $total_recouvrement_me + 
                                   $total_recouvrement_be - 
                                   $total_sortie_espece;

        $total_mvola_disponible = $total_mvola1 + 
                                  $total_mvola2 - 
                                  $total_recouvrement_me - 
                                  $total_recouvrement_mb + 
                                  $total_recouvrement_bm - 
                                  $total_sortie_mvola;

        $total_virement_disponible = $total_virement1 + 
                                     $total_virement2 - 
                                     $total_recouvrement_be - 
                                     $total_recouvrement_bm + 
                                     $total_recouvrement_mb - 
                                     $total_sortie_virement;

        // Vérifier selon le mode de paiement
        $montant_retire = (float) $decaissement['montant_retire'];
        $mode_paiement = $decaissement['mode_paiement'];
        $fonds_disponible = 0;
        $mode_paiement_label = '';

        switch ($mode_paiement) {
            case 'En espèce':
                $fonds_disponible = $total_espece_disponible;
                $mode_paiement_label = 'en espèce';
                break;
            
            case 'MVOLA':
                $fonds_disponible = $total_mvola_disponible;
                $mode_paiement_label = 'MVOLA';
                break;
            
            case 'Virement Bancaire':
                $fonds_disponible = $total_virement_disponible;
                $mode_paiement_label = 'virement bancaire';
                break;
        }

        // ✅ VÉRIFICATION: Fonds suffisants ?
        if ($montant_retire > $fonds_disponible) {
            return $this->response->setJSON([
                'success' => false,
                'messages' => '❌ Paiement impossible — fonds ' . $mode_paiement_label . ' insuffisants.<br>' .
                             '<strong>Disponible:</strong> ' . number_format($fonds_disponible, 0, ',', ' ') . ' Ar<br>' .
                             '<strong>Demandé:</strong> ' . number_format($montant_retire, 0, ',', ' ') . ' Ar<br><br>' .
                             '<em>Soldes actuels:</em><br>' .
                             '• Espèce: ' . number_format($total_espece_disponible, 0, ',', ' ') . ' Ar<br>' .
                             '• MVOLA: ' . number_format($total_mvola_disponible, 0, ',', ' ') . ' Ar<br>' .
                             '• Virement: ' . number_format($total_virement_disponible, 0, ',', ' ') . ' Ar'
            ]);
        }
        
        // ✅ Fonds suffisants, on procède au paiement
        $data = [
            'statut' => 'Payé',
            'date_paiement_effectif' => date('Y-m-d H:i:s')
        ];
        
        $result = $SortieCaisse->updateSortieCaisse($id_sortie, $data);
        
        if ($result) {
            // Créer une notification pour TOUS les DAF, Direction et SuperAdmin
            try {
                if (class_exists('App\Controllers\NotificationController')) {
                    $Notification = new NotificationController();
                    
                    $montant = number_format($decaissement['montant_retire'], 0, ',', ' ');
                    $message = "💰 Décaissement payé - " . $montant . " Ar (" . $mode_paiement . ")<br>" .
                              "Motif: " . $decaissement['motif'] . "<br>" .
                              "Caissière: " . $users['firstname'] . ' ' . $users['lastname'] . "<br>" .
                              "Store: " . $this->returnStoreName($decaissement['store_id']) . "<br>" .
                              "Nouveau solde " . $mode_paiement_label . ": " . number_format($fonds_disponible - $montant_retire, 0, ',', ' ') . " Ar";
                    
                    $Stores = new Stores();
                    $allStores = $Stores->getActiveStore();
                    
                    if (is_array($allStores) && count($allStores) > 0) {
                        foreach ($allStores as $store) {
                            $Notification->createNotification($message, "Direction", (int)$store['id'], 'sortieCaisse');
                            $Notification->createNotification($message, "DAF", (int)$store['id'], 'sortieCaisse');
                            $Notification->createNotification($message, "SuperAdmin", (int)$store['id'], 'sortieCaisse');
                        }
                    }
                }
            } catch (\Exception $e) {
                log_message('error', 'Erreur notification markAsPaid: ' . $e->getMessage());
            }
            
            return $this->response->setJSON([
                'success' => true,
                'messages' => '✅ Décaissement marqué comme <strong>PAYÉ</strong><br>' .
                             'Montant: ' . number_format($decaissement['montant_retire'], 0, ',', ' ') . ' Ar (' . $mode_paiement . ')<br>' .
                             'Nouveau solde ' . $mode_paiement_label . ': ' . number_format($fonds_disponible - $montant_retire, 0, ',', ' ') . ' Ar<br>' .
                             '<em>Tous les Direction, DAF et SuperAdmin ont été notifiés.</em>'
            ]);
        
        } else {
            return $this->response->setJSON([
                'success' => false,
                'messages' => 'Erreur lors de la mise à jour du statut.'
            ]);
        }
        
    } catch (\Exception $e) {
        log_message('error', 'Erreur markAsPaid: ' . $e->getMessage() . ' | Ligne: ' . $e->getLine());
        return $this->response->setJSON([
            'success' => false,
            'messages' => 'Erreur serveur: ' . $e->getMessage()
        ]);
    }
}
    public function fetchSortieCaisseData1()
    {
        helper(['url', 'form']);
        $SortieCaisse = new SortieCaisse();
    
        // Initialiser les variables pour DataTables
        $draw = intval($this->request->getVar('draw'));
    
        $data = $SortieCaisse->getAllSortieCaisse1();
        $totalRecords = count($data);
    
        $session = session();
        $users = $session->get('user');
        
        // ✅ Vérifier si l'utilisateur est DAF ou Direction UNIQUEMENT
        $canManage = in_array($users['group_name'], ['Direction', 'DAF','SuperAdmin']);
        $isCaissiere = $users['group_name'] === 'Caissière';
        
        $result = [
            "draw"            => $draw,
            "recordsTotal"    => $totalRecords,
            "recordsFiltered" => $totalRecords,
            "data"            => []
        ];
    
        foreach ($data as $key => $value) {
            $buttons = '';
            
            // ✅ BOUTON MODIFICATION : Seulement pour DAF et Direction
            if (in_array('updateSortieCaisse', $this->permission) && $canManage) {
                $buttons .= '<button type="button" class="btn btn-default" onclick="editFunc(' . $value['id_sortie'] . ')" data-toggle="modal" data-target="#updateModal"><i class="fa fa-pencil"></i></button>';
            }
            
            // ✅ BOUTON VALIDATION : Seulement pour DAF et Direction
            if (in_array('validateSortieCaisse', $this->permission) && $canManage) {
                $buttons .= '<button type="button" class="btn btn-default" onclick="validateFunc(' . $value['id_sortie'] . ')"><i class="fa fa-check-circle"></i></button>';
            }
            
            // ✅ NOUVEAU : BOUTON "MARQUER COMME PAYÉ" pour Caissière
            if ($isCaissiere && $value['statut'] === 'Valider') {
                $buttons .= '<button type="button" class="btn btn-success btn-sm" onclick="markAsPaidFunc(' . $value['id_sortie'] . ')" title="Marquer comme payé"><i class="fa fa-money"></i> Payé</button>';
            }
            
            // Afficher un badge si déjà payé
            if ($value['statut'] === 'Payé') {
                $buttons .= '<span class="label label-success"><i class="fa fa-check"></i> Payé</span>';
            }
            
            if($users["group_name"] === "Caissière"){
                $result['data'][$key] = [
                    $value['id_sortie'],
                    number_format($value['montant_retire'], 0, '.', ' '),
                    $value['date_retrait'],
                    $value['sortie_personnel'],
                    $value['motif'],
                    $value['statut'],
                    $value['admin_raison'],
                    $buttons  // Les caissières ne verront PAS les boutons
                ];
            }
            elseif ($users["group_name"] === "Direction" || $users["group_name"] === "DAF" || $users["group_name"] === "SuperAdmin") {
                $result['data'][$key] = [
                    $value['id_sortie'],
                    number_format($value['montant_retire'], 0, '.', ' '),
                    $value['date_retrait'],
                    $value['sortie_personnel'],
                    $value['motif'],
                    $value['source_fond'],
                    $value['initiateur_demande'],
                    $this->returnStoreName($value['store_id']),
                    $value['commentaire'],
                    $value['statut'],
                    $buttons  // DAF et Direction verront les boutons
                ];
            }
            elseif ($users["group_name"] === "Conseil") {
                // ✅ Conseil peut voir les données mais SANS boutons d'action
                $result['data'][$key] = [
                    $value['id_sortie'],
                    number_format($value['montant_retire'], 0, '.', ' '),
                    $value['date_retrait'],
                    $value['sortie_personnel'],
                    $value['motif'],
                    $value['source_fond'],
                    $value['initiateur_demande'],
                    $this->returnStoreName($value['store_id']),
                    $value['commentaire'],
                    $value['statut'],
                    ''  // Pas de boutons pour Conseil
                ];
            }
        }
        return $this->response->setJSON($result);
    }
    private function returnStoreName(int $id)
    {
        $Stores = new Stores();
        $stor = $Stores->getActiveStore();
        $Storename = "";
        foreach ($stor as $key => $value) {
            if ($value['id'] == $id) {
                $Storename = $value['name'];
            }
        }

        return $Storename;
    }

    public function createSortieCaisse()
    {
        $this->verifyRole('createSortieCaisse');
    
        $validation = \Config\Services::validation();
    
        $validation->setRules([
            'montant_retire' => 'required|numeric',
            'motif_select' => 'required',
            'nom' => 'required',
            'fonction' => 'required',
            'mode_paiement' => 'required',
            'montant_lettre' => 'required',
            'date_demande' => 'required'
        ]);
    
        if (!$validation->withRequest($this->request)->run()) {
            return $this->response->setJSON([
                'success' => false, 
                'messages' => $validation->getErrors()
            ]);
        }
    
        try {
            $session = session();
            $user = $session->get('user');
    
            // Nettoyage et conversion du montant
            $montant_retire_raw = $this->request->getPost('montant_retire');
            $montant_retire = (float) str_replace([' ', ','], ['', '.'], $montant_retire_raw);
            
            // Récupérer le mode de paiement
            $mode_paiement = $this->request->getPost('mode_paiement');
    
            if ($montant_retire <= 0) {
                return $this->response->setJSON([
                    'success' => false,
                    'messages' => 'Le montant doit être supérieur à 0'
                ]);
            }
    
            // ✅ SUPPRESSION: Plus besoin de vérifier les fonds disponibles à la création
            // La vérification se fera au moment du paiement effectif par la caissière
    
            // PRÉPARATION DES DONNÉES
            $motif = $this->request->getPost('motif_select');
            
            $data = [
                'montant_retire' => $montant_retire,
                'date_retrait' => date('Y-m-d H:i:s'),
                'motif' => $motif,
                'commentaire' => $this->request->getPost('sortie_commentaire') ?? '',
                'fournisseur' => $this->request->getPost('sortie_fournisseur') ?? '',
                'nif_cin' => $this->request->getPost('sortie_nif') ?? '',
                'statistique' => $this->request->getPost('sortie_statistique') ?? '',
                'telephone' => $this->request->getPost('sortie_phone') ?? '',
                'code_postal' => $this->request->getPost('sortie_adresse') ?? '',
                'statut' => 'En attente',
                'user_id' => $user['id'],
                'store_id' => $user['store_id'],
                'admin_raison' => '',
                'sortie_personnel' => $user['firstname'] . ' ' . $user['lastname'],
                'nom_demandeur' => $this->request->getPost('nom'),
                'fonction_demandeur' => $this->request->getPost('fonction'),
                'mode_paiement' => $mode_paiement,
                'montant_lettre' => $this->request->getPost('montant_lettre'),
                'date_demande' => $this->request->getPost('date_demande'),
                'reference' => $this->request->getPost('reference') ?? ''
            ];
    
            // Mapping source_fond et initiateur
            if (isset($this->mapping[$motif])) {
                $data['source_fond'] = $this->mapping[$motif]['source_fond'];
                $data['initiateur_demande'] = $this->mapping[$motif]['initiateur_demande'];
            } else {
                $data['source_fond'] = 'Caisse Courante';
                $data['initiateur_demande'] = 'Caissière';
            }
    
            // Champs supplémentaires pour montant > 1,000,000
            if ($montant_retire >= 1000000) {
                $data['numero_fiche'] = $this->request->getPost('numero_fiche') ?? '';
                $data['date_fiche'] = $this->request->getPost('date_fiche') ?? null;
                $data['service_demandeur'] = $this->request->getPost('service_demandeur') ?? '';
                $data['objet_depense'] = $this->request->getPost('objet_depense') ?? '';
                $data['nature_depense'] = $this->request->getPost('nature_depense') ?? '';
                $data['montant_estime'] = $this->request->getPost('montant_estime') ?? '';
                $data['mode_reglement'] = $this->request->getPost('mode_reglement') ?? '';
                $data['date_paiement_prevue'] = $this->request->getPost('date_paiement_prevue') ?? null;
                
                $justificatifs = $this->request->getPost('justificatifs');
                if (is_array($justificatifs) && count($justificatifs) > 0) {
                    $data['justificatifs'] = json_encode($justificatifs);
                }
                
                $data['visa_demandeur'] = $this->request->getPost('visa_demandeur') ?? '';
                $data['date_visa_demandeur'] = $this->request->getPost('date_visa_demandeur') ?? null;
                $data['visa_chef_service'] = $this->request->getPost('visa_chef_service') ?? '';
                $data['date_visa_chef_service'] = $this->request->getPost('date_visa_chef_service') ?? null;
                $data['visa_direction'] = $this->request->getPost('visa_direction') ?? '';
                $data['date_visa_direction'] = $this->request->getPost('date_visa_direction') ?? null;
                $data['visa_superAdmin'] = $this->request->getPost('visa_superAdmin') ?? '';
                $data['date_visa_superAdmin'] = $this->request->getPost('date_visa_superAdmin') ?? null;
                $data['observations'] = $this->request->getPost('observations') ?? '';
            }
    
            // Gestion du fichier
            $preuveFile = $this->request->getFile('sortie_preuve');
            if ($preuveFile && $preuveFile->isValid() && !$preuveFile->hasMoved()) {
                $newName = $preuveFile->getRandomName();
                $uploadPath = WRITEPATH . 'uploads/sortie_caisse';
                
                if (!is_dir($uploadPath)) {
                    mkdir($uploadPath, 0755, true);
                }
                
                $preuveFile->move($uploadPath, $newName);
                $data['preuve_achat'] = $newName;
                $data['mime_type'] = $preuveFile->getClientMimeType();
            }
    
            // INSERTION EN BASE
            $model = new SortieCaisse();
            $result = $model->addSortieCaisse($data);
    
            if ($result) {
                // Notification pour TOUS les Direction, DAF et SuperAdmin
                try {
                    if (class_exists('App\Controllers\NotificationController')) {
                        $Notification = new NotificationController();
                        
                        $message = "Nouvelle demande de décaissement de " . 
                                   number_format($montant_retire, 0, ',', ' ') . " Ar (" . $mode_paiement . ")<br>" .
                                   "Store: " . $this->returnStoreName($user['store_id']) . "<br>" .
                                   "Demandeur: " . $user['firstname'] . ' ' . $user['lastname'];
                        
                        $Stores = new Stores();
                        $allStores = $Stores->getActiveStore();
                        
                        if (is_array($allStores) && count($allStores) > 0) {
                            foreach ($allStores as $store) {
                                $Notification->createNotification($message, "Direction", (int)$store['id'], 'sortieCaisse');
                                $Notification->createNotification($message, "DAF", (int)$store['id'], 'sortieCaisse');
                                $Notification->createNotification($message, "SuperAdmin", (int)$store['id'], 'sortieCaisse');
                            }
                        }
                    }
                } catch (\Exception $e) {
                    log_message('error', 'Erreur notification createSortieCaisse: ' . $e->getMessage());
                }
                
                return $this->response->setJSON([
                    'success' => true, 
                    'messages' => 'Décaissement de ' . number_format($montant_retire, 0, ',', ' ') . ' Ar créé avec succès<br>' .
                                 'Mode de paiement: ' . $mode_paiement . '<br>' .
                                 '<em>En attente de validation</em>'
                ]);
            
            } else {
                return $this->response->setJSON([
                    'success' => false, 
                    'messages' => 'Erreur lors de l\'enregistrement en base de données'
                ]);
            }
    
        } catch (\Exception $e) {
            log_message('error', 'Erreur createSortieCaisse: ' . $e->getMessage() . ' | Ligne: ' . $e->getLine());
            return $this->response->setJSON([
                'success' => false, 
                'messages' => 'Erreur serveur: ' . $e->getMessage()
            ]);
        }
    }
    public function updateSortieCaisse($id_sortie)
    {
        $this->verifyRole('updateSortieCaisse');
    
        $data['page_title'] = $this->pageTitle;
    
        if ($this->request->getMethod() === 'post') {
            $validation = \Config\Services::validation();
        
            $validation->setRules([
                'montant_retire_edit' => 'required|numeric',
                'nom_edit' => 'required',
                'fonction_edit' => 'required',
                'date_demande_edit' => 'required'
            ]);
        
            if (!$validation->withRequest($this->request)->run()) {
                return $this->response->setJSON([
                    'success' => false, 
                    'messages' => $validation->getErrors()
                ]);
            }
    
            try {
                $session = session();
                $users = $session->get('user');
    
                $sortieCaisse = new SortieCaisse();
                $currentSortie = $sortieCaisse->getSortieCaisseSingle($id_sortie);
                
                if (!$currentSortie) {
                    return $this->response->setJSON([
                        'success' => false,
                        'messages' => 'Décaissement introuvable'
                    ]);
                }
    
                // ✅ EMPÊCHER LA MODIFICATION SI DÉJÀ PAYÉ
                if ($currentSortie['statut'] === 'Payé') {
                    return $this->response->setJSON([
                        'success' => false,
                        'messages' => 'Impossible de modifier un décaissement déjà payé.'
                    ]);
                }
    
                $montant_retire_raw = $this->request->getPost('montant_retire_edit');
                $montant_retire = (float) str_replace([' ', ','], ['', '.'], $montant_retire_raw);
                
                $motif = $this->request->getPost('motif_select_edit') ?: $this->request->getPost('motif_select_edit_hidden');
                $mode_paiement = $this->request->getPost('mode_paiement_edit');
    
                if ($montant_retire <= 0) {
                    return $this->response->setJSON([
                        'success' => false,
                        'messages' => 'Le montant doit être supérieur à 0'
                    ]);
                }
    
                // ✅ SUPPRESSION: Plus de vérification des fonds à la modification
                // La vérification se fera uniquement au moment du paiement
    
                $data = [
                    'montant_retire' => $montant_retire,
                    'date_retrait' => date('Y-m-d H:i:s'),
                    'motif' => $motif,
                    'commentaire' => $this->request->getPost('sortie_commentaire_edit') ?? '',
                    'fournisseur' => $this->request->getPost('sortie_fournisseur_edit') ?? '',
                    'nif_cin' => $this->request->getPost('sortie_nif_edit') ?? '',
                    'statistique' => $this->request->getPost('sortie_statistique_edit') ?? '',
                    'telephone' => $this->request->getPost('sortie_phone_edit') ?? '',
                    'code_postal' => $this->request->getPost('sortie_adresse_edit') ?? '',
                    'sortie_personnel' => $users['firstname'] . ' ' . $users['lastname'],
                    'store_id' => $users['store_id'],
                    'nom_demandeur' => $this->request->getPost('nom_edit'),
                    'fonction_demandeur' => $this->request->getPost('fonction_edit'),
                    'mode_paiement' => $mode_paiement,
                    'montant_lettre' => $this->request->getPost('montant_lettre_edit'),
                    'date_demande' => $this->request->getPost('date_demande_edit'),
                    'reference' => $this->request->getPost('reference_edit') ?? ''
                ];
    
                if (isset($this->mapping[$motif])) {
                    $data['source_fond'] = $this->mapping[$motif]['source_fond'];
                    $data['initiateur_demande'] = $this->mapping[$motif]['initiateur_demande'];
                } else {
                    $data['source_fond'] = 'Caisse Courante';
                    $data['initiateur_demande'] = 'Caissière';
                }
    
                $preuveFile = $this->request->getFile('sortie_preuve_edit');
                if ($preuveFile && $preuveFile->isValid() && !$preuveFile->hasMoved()) {
                    $newName = $preuveFile->getRandomName();
                    $uploadPath = WRITEPATH . 'uploads/sortie_caisse';
                    
                    if (!is_dir($uploadPath)) {
                        mkdir($uploadPath, 0755, true);
                    }
                    
                    $preuveFile->move($uploadPath, $newName);
                    $data['preuve_achat'] = $newName;
                    $data['mime_type'] = $preuveFile->getClientMimeType();
                }
    
                if ($sortieCaisse->updateSortieCaisse($id_sortie, $data)) {
                    return $this->response->setJSON([
                        'success' => true,
                        'messages' => 'Décaissement modifié avec succès !<br>' .
                                     'Nouveau montant: ' . number_format($montant_retire, 0, ',', ' ') . ' Ar (' . $mode_paiement . ')'
                    ]);
                } else {
                    return $this->response->setJSON([
                        'success' => false,
                        'messages' => 'Erreur lors de la modification en base de données'
                    ]);
                }
    
            } catch (\Exception $e) {
                log_message('error', 'Erreur updateSortieCaisse: ' . $e->getMessage() . ' | Ligne: ' . $e->getLine());
                return $this->response->setJSON([
                    'success' => false,
                    'messages' => 'Erreur serveur: ' . $e->getMessage()
                ]);
            }
        }
    }
    public function fetchSortieCaisseSingle($id)
    {
        if ($id) {
            $SortieCaisse = new SortieCaisse();
            $data = $SortieCaisse->getSortieCaisseSingle($id);
            echo json_encode($data);
        }
    }

    public function validateSortieCaisse($id_sortie) {
        $this->verifyRole('validateSortieCaisse');

        $data['page_title'] = $this->pageTitle;

        if ($this->request->getMethod() === 'post') {
            $data = [
                'admin_raison' => $this->request->getPost('admin_raison'),
                'statut' => $this->request->getPost('statut'),
            ];
            
            $session = session();
            $users = $session->get('user');
            $SortieCaisse = new SortieCaisse();
            $Notification = new NotificationController();
            
            if ($SortieCaisse->updateSortieCaisse($id_sortie, $data)) {
                $statut = $this->request->getPost('statut');
                $message = '';
                
                // ✅ Récupérer le décaissement pour avoir son store_id
                $decaissement = $SortieCaisse->getSortieCaisseSingle($id_sortie);
                $store_id = $decaissement['store_id'];
                
                switch ($statut) {
                    case "Valider":
                        $message = "✅ Le décaissement a été validé par la Direction<br>Store: " . $this->returnStoreName($store_id);
                        $Notification->createNotification($message, "Caissière", (int)$store_id, 'sortieCaisse');
                        break;
                    case "Refuser":
                        $message = "❌ Le décaissement a été refusé par la Direction<br>Store: " . $this->returnStoreName($store_id) . "<br>Raison: " . $this->request->getPost('admin_raison');
                        $Notification->createNotification($message, "Caissière", (int)$store_id, 'sortieCaisse');
                        break;
                    case "En attente":
                        $message = "⏳ Le décaissement a été mis en attente par la Direction<br>Store: " . $this->returnStoreName($store_id);
                        $Notification->createNotification($message, "Caissière", (int)$store_id, 'sortieCaisse');
                        break;
                }
                
                return $this->response->setJSON([
                    'success' => true,
                    'messages' => 'Décaissement modifié avec succès ! Notification envoyée à la caissière de ' . $this->returnStoreName($store_id)
                ]);
            } else {
                return $this->response->setJSON([
                    'success' => false,
                    'messages' => 'Erreur lors de la modification du décaissement. Veuillez réessayer.'
                ]);
            }   
        } 
    }
    /**
 * Exporter les décaissements en Excel
 */
public function exportExcel()
{
    $this->verifyRole('viewSortieCaisse');
    
    try {
        $SortieCaisse = new SortieCaisse();
        $data = $SortieCaisse->getAllSortieCaisse();
        
        $session = session();
        $user = $session->get('user');
        
        // Créer un nouveau Spreadsheet
        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();
        
        // Définir le titre
        $sheet->setTitle('Décaissements');
        
        // En-têtes selon le groupe de l'utilisateur
        if ($user["group_name"] === "Caissière") {
            $headers = [
                'ID',
                'Montant Retiré (Ar)',
                'Date Retrait',
                'Personnel',
                'Motif',
                'Statut',
                'Raison Admin'
            ];
        } else {
            $headers = [
                'ID',
                'Montant Retiré (Ar)',
                'Date Retrait',
                'Personnel',
                'Motif',
                'Source Fond',
                'Initiateur',
                'Magasin',
                'Commentaire',
                'Statut'
            ];
        }
        
        // Écrire les en-têtes
        $col = 'A';
        foreach ($headers as $header) {
            $sheet->setCellValue($col . '1', $header);
            $sheet->getStyle($col . '1')->applyFromArray([
                'font' => [
                    'bold' => true,
                    'color' => ['rgb' => 'FFFFFF']
                ],
                'fill' => [
                    'fillType' => Fill::FILL_SOLID,
                    'startColor' => ['rgb' => '4472C4']
                ],
                'alignment' => [
                    'horizontal' => Alignment::HORIZONTAL_CENTER,
                    'vertical' => Alignment::VERTICAL_CENTER
                ]
            ]);
            $col++;
        }
        
        // Remplir les données
        $row = 2;
        foreach ($data as $item) {
            if ($user["group_name"] === "Caissière") {
                $sheet->setCellValue('A' . $row, $item['id_sortie']);
                $sheet->setCellValue('B' . $row, number_format($item['montant_retire'], 0, '.', ' '));
                $sheet->setCellValue('C' . $row, $item['date_retrait']);
                $sheet->setCellValue('D' . $row, $item['sortie_personnel']);
                $sheet->setCellValue('E' . $row, $item['motif']);
                $sheet->setCellValue('F' . $row, $item['statut']);
                $sheet->setCellValue('G' . $row, $item['admin_raison']);
            } else {
                $sheet->setCellValue('A' . $row, $item['id_sortie']);
                $sheet->setCellValue('B' . $row, number_format($item['montant_retire'], 0, '.', ' '));
                $sheet->setCellValue('C' . $row, $item['date_retrait']);
                $sheet->setCellValue('D' . $row, $item['sortie_personnel']);
                $sheet->setCellValue('E' . $row, $item['motif']);
                $sheet->setCellValue('F' . $row, $item['source_fond']);
                $sheet->setCellValue('G' . $row, $item['initiateur_demande']);
                $sheet->setCellValue('H' . $row, $this->returnStoreName($item['store_id']));
                $sheet->setCellValue('I' . $row, $item['commentaire']);
                $sheet->setCellValue('J' . $row, $item['statut']);
            }
            $row++;
        }
        
        // Auto-dimensionner les colonnes
        foreach (range('A', $col) as $columnID) {
            $sheet->getColumnDimension($columnID)->setAutoSize(true);
        }
        
        // Ajouter des bordures
        $styleArray = [
            'borders' => [
                'allBorders' => [
                    'borderStyle' => Border::BORDER_THIN,
                    'color' => ['rgb' => '000000']
                ]
            ]
        ];
        $sheet->getStyle('A1:' . $col . ($row - 1))->applyFromArray($styleArray);
        
        // Générer le fichier
        $writer = new Xlsx($spreadsheet);
        $filename = 'decaissements_' . date('Y-m-d_His') . '.xlsx';
        
        // Envoyer le fichier au navigateur
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment;filename="' . $filename . '"');
        header('Cache-Control: max-age=0');
        
        $writer->save('php://output');
        exit;
        
    } catch (\Exception $e) {
        log_message('error', 'Erreur exportExcel: ' . $e->getMessage());
        return $this->response->setJSON([
            'success' => false,
            'messages' => 'Erreur lors de l\'exportation: ' . $e->getMessage()
        ]);
    }
}

/**
 * Exporter les décaissements en CSV
 */
public function exportCsv()
{
    $this->verifyRole('viewSortieCaisse');
    
    try {
        $SortieCaisse = new SortieCaisse();
        $data = $SortieCaisse->getAllSortieCaisse();
        
        $session = session();
        $user = $session->get('user');
        
        // Créer un nouveau Spreadsheet
        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();
        
        // En-têtes selon le groupe de l'utilisateur
        if ($user["group_name"] === "Caissière") {
            $headers = [
                'ID',
                'Montant Retiré (Ar)',
                'Date Retrait',
                'Personnel',
                'Motif',
                'Statut',
                'Raison Admin'
            ];
        } else {
            $headers = [
                'ID',
                'Montant Retiré (Ar)',
                'Date Retrait',
                'Personnel',
                'Motif',
                'Source Fond',
                'Initiateur',
                'Magasin',
                'Commentaire',
                'Statut'
            ];
        }
        
        // Écrire les en-têtes
        $col = 'A';
        foreach ($headers as $header) {
            $sheet->setCellValue($col . '1', $header);
            $col++;
        }
        
        // Remplir les données
        $row = 2;
        foreach ($data as $item) {
            if ($user["group_name"] === "Caissière") {
                $sheet->setCellValue('A' . $row, $item['id_sortie']);
                $sheet->setCellValue('B' . $row, number_format($item['montant_retire'], 0, '.', ' '));
                $sheet->setCellValue('C' . $row, $item['date_retrait']);
                $sheet->setCellValue('D' . $row, $item['sortie_personnel']);
                $sheet->setCellValue('E' . $row, $item['motif']);
                $sheet->setCellValue('F' . $row, $item['statut']);
                $sheet->setCellValue('G' . $row, $item['admin_raison']);
            } else {
                $sheet->setCellValue('A' . $row, $item['id_sortie']);
                $sheet->setCellValue('B' . $row, number_format($item['montant_retire'], 0, '.', ' '));
                $sheet->setCellValue('C' . $row, $item['date_retrait']);
                $sheet->setCellValue('D' . $row, $item['sortie_personnel']);
                $sheet->setCellValue('E' . $row, $item['motif']);
                $sheet->setCellValue('F' . $row, $item['source_fond']);
                $sheet->setCellValue('G' . $row, $item['initiateur_demande']);
                $sheet->setCellValue('H' . $row, $this->returnStoreName($item['store_id']));
                $sheet->setCellValue('I' . $row, $item['commentaire']);
                $sheet->setCellValue('J' . $row, $item['statut']);
            }
            $row++;
        }
        
        // Générer le fichier CSV
        $writer = new CsvWriter($spreadsheet);
        $writer->setDelimiter(';');
        $writer->setEnclosure('"');
        $writer->setLineEnding("\r\n");
        $writer->setSheetIndex(0);
        
        $filename = 'decaissements_' . date('Y-m-d_His') . '.csv';
        
        // Envoyer le fichier au navigateur
        header('Content-Type: text/csv');
        header('Content-Disposition: attachment;filename="' . $filename . '"');
        header('Cache-Control: max-age=0');
        
        $writer->save('php://output');
        exit;
        
    } catch (\Exception $e) {
        log_message('error', 'Erreur exportCsv: ' . $e->getMessage());
        return $this->response->setJSON([
            'success' => false,
            'messages' => 'Erreur lors de l\'exportation: ' . $e->getMessage()
        ]);
    }
}

/**
 * Exporter avec filtres (optionnel)
 */
public function exportWithFilters()
{
    $this->verifyRole('viewSortieCaisse');
    
    $format = $this->request->getGet('format'); // 'excel' ou 'csv'
    $dateDebut = $this->request->getGet('date_debut');
    $dateFin = $this->request->getGet('date_fin');
    $statut = $this->request->getGet('statut');
    
    try {
        $SortieCaisse = new SortieCaisse();
        
        // Récupérer les données avec filtres
        $builder = $SortieCaisse->builder();
        
        if ($dateDebut) {
            $builder->where('date_retrait >=', $dateDebut);
        }
        if ($dateFin) {
            $builder->where('date_retrait <=', $dateFin);
        }
        if ($statut) {
            $builder->where('statut', $statut);
        }
        
        $data = $builder->get()->getResultArray();
        
        $session = session();
        $user = $session->get('user');
        
        // Créer le Spreadsheet
        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();
        $sheet->setTitle('Décaissements Filtrés');
        
        // En-têtes
        if ($user["group_name"] === "Caissière") {
            $headers = ['ID', 'Montant Retiré (Ar)', 'Date Retrait', 'Personnel', 'Motif', 'Statut', 'Raison Admin'];
        } else {
            $headers = ['ID', 'Montant Retiré (Ar)', 'Date Retrait', 'Personnel', 'Motif', 'Source Fond', 'Initiateur', 'Magasin', 'Commentaire', 'Statut'];
        }
        
        $col = 'A';
        foreach ($headers as $header) {
            $sheet->setCellValue($col . '1', $header);
            $sheet->getStyle($col . '1')->applyFromArray([
                'font' => ['bold' => true, 'color' => ['rgb' => 'FFFFFF']],
                'fill' => ['fillType' => Fill::FILL_SOLID, 'startColor' => ['rgb' => '4472C4']],
                'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER]
            ]);
            $col++;
        }
        
        // Remplir les données
        $row = 2;
        foreach ($data as $item) {
            if ($user["group_name"] === "Caissière") {
                $sheet->setCellValue('A' . $row, $item['id_sortie']);
                $sheet->setCellValue('B' . $row, number_format($item['montant_retire'], 0, '.', ' '));
                $sheet->setCellValue('C' . $row, $item['date_retrait']);
                $sheet->setCellValue('D' . $row, $item['sortie_personnel']);
                $sheet->setCellValue('E' . $row, $item['motif']);
                $sheet->setCellValue('F' . $row, $item['statut']);
                $sheet->setCellValue('G' . $row, $item['admin_raison']);
            } else {
                $sheet->setCellValue('A' . $row, $item['id_sortie']);
                $sheet->setCellValue('B' . $row, number_format($item['montant_retire'], 0, '.', ' '));
                $sheet->setCellValue('C' . $row, $item['date_retrait']);
                $sheet->setCellValue('D' . $row, $item['sortie_personnel']);
                $sheet->setCellValue('E' . $row, $item['motif']);
                $sheet->setCellValue('F' . $row, $item['source_fond']);
                $sheet->setCellValue('G' . $row, $item['initiateur_demande']);
                $sheet->setCellValue('H' . $row, $this->returnStoreName($item['store_id']));
                $sheet->setCellValue('I' . $row, $item['commentaire']);
                $sheet->setCellValue('J' . $row, $item['statut']);
            }
            $row++;
        }
        
        // Auto-dimensionner
        foreach (range('A', $col) as $columnID) {
            $sheet->getColumnDimension($columnID)->setAutoSize(true);
        }
        
        // Générer selon le format
        if ($format === 'csv') {
            $writer = new CsvWriter($spreadsheet);
            $writer->setDelimiter(';');
            $filename = 'decaissements_filtres_' . date('Y-m-d_His') . '.csv';
            header('Content-Type: text/csv');
        } else {
            $writer = new Xlsx($spreadsheet);
            $filename = 'decaissements_filtres_' . date('Y-m-d_His') . '.xlsx';
            header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        }
        
        header('Content-Disposition: attachment;filename="' . $filename . '"');
        header('Cache-Control: max-age=0');
        
        $writer->save('php://output');
        exit;
        
    } catch (\Exception $e) {
        log_message('error', 'Erreur exportWithFilters: ' . $e->getMessage());
        return $this->response->setJSON([
            'success' => false,
            'messages' => 'Erreur lors de l\'exportation: ' . $e->getMessage()
        ]);
    }
}
}