<?php

namespace App\Controllers;

use App\Controllers\AdminController;
use App\Models\Orders;
use App\Models\Recouvrement;
use App\Models\SortieCaisse;
use App\Models\Avance;
use App\Models\Stores;

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

    private $pageTitle = 'Recouvrements';

        public function index()
    {
        $this->verifyRole('viewRecouvrement');

        $data = $this->getTotalsArray();

        $this->render_template('recouvrement/index', $data);
    }


    // Create an AJAX endpoint to access the fetchTotal() function
    public function getTotalData()
    {
        echo $this->fetchTotal();
        exit;
    }

        public function fetchTotal()
    {
        $data = $this->getTotalsArray();

        return $this->response->setJSON($data);
    }

    private function getTotalsArray(): array
    {
        $orders        = new Orders();
        $recouvrement  = new Recouvrement();
        $sortieCaisse  = new SortieCaisse();
        $avance        = new Avance();
    
        // Récupère les données brutes
        $paymentDataOrders = $orders->getPaymentModes();
        $paymentDataAvance = $avance->getPaymentModesAvance();
        $totalRecouvrement = $recouvrement->getTotalRecouvrements();
        $total_sortie_caisse = $sortieCaisse->getTotalSortieCaisse();
    
        // === EXTRACTION DES SORTIES PAR MODE DE PAIEMENT ===
        $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;
    
        // === TOTAUX RECOUVREMENT ===
        $me = isset($totalRecouvrement->me) ? (float) $totalRecouvrement->me : 0;
        $bm = isset($totalRecouvrement->bm) ? (float) $totalRecouvrement->bm : 0;
        $be = isset($totalRecouvrement->be) ? (float) $totalRecouvrement->be : 0;
        $mb = isset($totalRecouvrement->mb) ? (float) $totalRecouvrement->mb : 0;
    
        // === TOTAUX PAIEMENTS ORDERS ===
        $total_orders = isset($paymentDataOrders->total) ? (float) $paymentDataOrders->total : 0;
        $mv1_orders = isset($paymentDataOrders->total_mvola1) ? (float) $paymentDataOrders->total_mvola1 : 0;
        $mv2_orders = isset($paymentDataOrders->total_mvola2) ? (float) $paymentDataOrders->total_mvola2 : 0;
        $es1_orders = isset($paymentDataOrders->total_espece1) ? (float) $paymentDataOrders->total_espece1 : 0;
        $es2_orders = isset($paymentDataOrders->total_espece2) ? (float) $paymentDataOrders->total_espece2 : 0;
        $vb1_orders = isset($paymentDataOrders->total_virement_bancaire1) ? (float) $paymentDataOrders->total_virement_bancaire1 : 0;
        $vb2_orders = isset($paymentDataOrders->total_virement_bancaire2) ? (float) $paymentDataOrders->total_virement_bancaire2 : 0;
    
        // === TOTAUX PAIEMENTS AVANCES ===
        $total_avances = isset($paymentDataAvance->total) ? (float) $paymentDataAvance->total : 0;
        $mv_avances = isset($paymentDataAvance->total_mvola) ? (float) $paymentDataAvance->total_mvola : 0;
        $es_avances = isset($paymentDataAvance->total_espece) ? (float) $paymentDataAvance->total_espece : 0;
        $vb_avances = isset($paymentDataAvance->total_virement_bancaire) ? (float) $paymentDataAvance->total_virement_bancaire : 0;
    
        // === COMBINAISON ORDERS + AVANCES ===
        $total_mvola = $mv1_orders + $mv2_orders + $mv_avances;
        $total_espece = $es1_orders + $es2_orders + $es_avances;
        $total_vb = $vb1_orders + $vb2_orders + $vb_avances;
        $total = $total_orders + $total_avances;
    
        // === AJUSTEMENTS AVEC RECOUVREMENTS ET SORTIES (PAR MODE DE PAIEMENT) ===
        $total_mvola_final = $total_mvola - 
                             $me - 
                             $mb + 
                             $bm - 
                             $total_sortie_mvola;
    
        $total_espece_final = $total_espece + 
                              $me + 
                              $be - 
                              $total_sortie_espece;
    
        $total_virement_bancaire_final = $total_vb - 
                                         $be - 
                                         $bm + 
                                         $mb - 
                                         $total_sortie_virement;
    
        // === CALCUL DU TOTAL GÉNÉRAL ===
        $total_sortie_global = $total_sortie_espece + $total_sortie_mvola + $total_sortie_virement;
        $total_final = $total - $total_sortie_global;
    
        return [
            'total'                   => $total_final,
            'total_mvola'             => $total_mvola_final,
            'total_espece'            => $total_espece_final,
            'total_virement_bancaire' => $total_virement_bancaire_final,
            'page_title'              => $this->pageTitle,
            'permission'              => $this->permission
        ];
    }
    public function fetchRecouvrementData()
    {
        helper(['url', 'form']);
        $Recouvrement = new Recouvrement();

        // Initialiser les variables pour DataTables
        $draw = intval($this->request->getVar('draw'));
        $session = session();
        $users = $session->get('user');
        if($users['group_name'] === "Caissière"){
            $data = $Recouvrement->getAllRecouvrements($users['id'] );
            $totalRecords = count($data); // Nombre total de recouvrements

            $result = [
                "draw" => $draw,
                "recordsTotal" => $totalRecords,
                "recordsFiltered" => $totalRecords,
                "data" => []
            ];

            foreach ($data as $key => $value) {
                $buttons = '';
                if (in_array('updateRecouvrement', $this->permission)) {
                    $buttons .= '<button type="button" class="btn btn-default" onclick="editFunc(' . $value['recouvrement_id'] . ')" data-toggle="modal" data-target="#updateModal"><i class="fa fa-pencil"></i></button>';
                }

                if (in_array('deleteRecouvrement', $this->permission)) {
                    $buttons .= ' <button type="button" class="btn btn-danger" onclick="removeFunc(' . $value['recouvrement_id'] . ')" data-toggle="modal" data-target="#removeModal"><i class="fa fa-trash"></i></button>';
                }
                $result['data'][$key] = [
                    $value['recouvrement_id'],
                    number_format($value['recouvrement_montant'], 0, '.', ' '),
                    $value['recouvrement_date'],
                    $value['recouvrement_personnel'],
                    $value['send_money'],
                    $value['get_money'],
                    $buttons
                ];
            }
            return $this->response->setJSON($result);
        }

        $data = $Recouvrement->getAllRecouvrements();
        $totalRecords = count($data); // Nombre total de recouvrements

        $result = [
            "draw" => $draw,
            "recordsTotal" => $totalRecords,
            "recordsFiltered" => $totalRecords,
            "data" => []
        ];

        foreach ($data as $key => $value) {
            $buttons = '';
            if (in_array('updateRecouvrement', $this->permission)) {
                $buttons .= '<button type="button" class="btn btn-default" onclick="editFunc(' . $value['recouvrement_id'] . ')" data-toggle="modal" data-target="#updateModal"><i class="fa fa-pencil"></i></button>';
            }

            if (in_array('deleteRecouvrement', $this->permission)) {
                $buttons .= ' <button type="button" class="btn btn-danger" onclick="removeFunc(' . $value['recouvrement_id'] . ')" data-toggle="modal" data-target="#removeModal"><i class="fa fa-trash"></i></button>';
            }
            $result['data'][$key] = [
                $value['recouvrement_id'],
                number_format($value['recouvrement_montant'], 0, '.', ' '),
                $value['recouvrement_date'],
                $value['recouvrement_personnel'],
                $value['send_money'],
                $value['get_money'],
                $buttons
            ];
        }
        return $this->response->setJSON($result);
    }


    public function removeRecouvrement()
    {
        $this->verifyRole('deleteRecouvrement');
        $recouvrement_id = $this->request->getPost('recouvrement_id');

        $response = [];

        if ($recouvrement_id) {
            $Recouvrement = new Recouvrement();
            
            // ✅ Récupérer les infos du recouvrement avant suppression
            $recouvrementData = $Recouvrement->getRecouvrementSingle($recouvrement_id);
            
            if ($Recouvrement->deleteRecouvrement($recouvrement_id)) {
                // ✅ Notification pour TOUS les Direction, DAF et SuperAdmin de TOUS les stores
                try {
                    if (class_exists('App\Controllers\NotificationController') && $recouvrementData) {
                        $Notification = new NotificationController();
                        $Stores = new Stores();
                        $allStores = $Stores->getActiveStore();
                        
                        $session = session();
                        $users = $session->get('user');
                        
                        $message = "🗑️ Recouvrement supprimé<br>" .
                                   "Montant: " . number_format($recouvrementData['recouvrement_montant'], 0, ',', ' ') . " Ar<br>" .
                                   "Par: " . $users['firstname'] . ' ' . $users['lastname'];
                        
                        // ✅ Notifier Direction, DAF et SuperAdmin de TOUS les stores
                        if (is_array($allStores) && count($allStores) > 0) {
                            foreach ($allStores as $store) {
                                $Notification->createNotification(
                                    $message, 
                                    "Direction", 
                                    (int)$store['id'],
                                    'recouvrement'
                                );
                                
                                $Notification->createNotification(
                                    $message, 
                                    "DAF", 
                                    (int)$store['id'],
                                    'recouvrement'
                                );
                                
                                $Notification->createNotification(
                                    $message, 
                                    "SuperAdmin", 
                                    (int)$store['id'],
                                    'recouvrement'
                                );
                            }
                        }
                    }
                } catch (\Exception $e) {
                    log_message('error', 'Erreur notification removeRecouvrement: ' . $e->getMessage());
                }
                
                $response['success'] = true;
                $response['messages'] = "Recouvrement supprimé avec succès !<br><em>Notification envoyée à tous les Direction, DAF et SuperAdmin</em>";
            } else {
                $response['success'] = false;
                $response['messages'] = "Erreur lors de la suppression du recouvrement.";
            }
        } else {
            $response['success'] = false;
            $response['messages'] = "Veuillez actualiser la page.";
        }
        return $this->response->setJSON($response);
    }


    public function createRecouvrement()
    {
        $this->verifyRole('createRecouvrement');
    
        $data['page_title'] = $this->pageTitle;
    
        // Load validation service
        $validation = \Config\Services::validation();
    
        $validation->setRules([
            'send_mode' => 'required',
            'get_mode' => 'required',
            'recouvrement_montant' => 'required',
            'recouvrement_date' => 'required',
        ]);
    
        $validationData = [
            'send_mode' => $this->request->getPost('send_mode'),
            'get_mode' => $this->request->getPost('get_mode'),
            'recouvrement_montant' => $this->request->getPost('recouvrement_montant'),
            'recouvrement_date' => $this->request->getPost('recouvrement_date'),
        ];
    
        $Notification = new NotificationController();
        $Recouvrement = new Recouvrement();
        $session = session();
        $users = $session->get('user');
        
        if ($users && isset($users['firstname'], $users['lastname'])) {
            $fullname = $users['firstname'] . ' ' . $users['lastname'];
        }
    
        if ($validation->run($validationData)) {
            $send_mode = $this->request->getPost('send_mode');
            $get_mode = $this->request->getPost('get_mode');
            $amount = (float) $this->request->getPost('recouvrement_montant');
    
            // Vérifier si le recouvrement est possible
            if (!$this->canMakeRecouvrement($send_mode, $get_mode, $amount)) {
                $response['success'] = false;
                $response['messages'] = 'Recouvrement impossible : solde insuffisant pour ce type de transaction';
                return $this->response->setJSON($response);
            }
    
            // Préparer les données
            $data = [
                'recouvrement_montant' => $amount,
                'recouvrement_date' => $this->request->getPost('recouvrement_date'),
                'recouvrement_personnel' => $fullname,
                'get_money' => $get_mode,
                'send_money' => $send_mode,
                'user_id' => $users['id'],
                'store_id' => $users['store_id'],
            ];
    
            if ($Recouvrement->addRecouvrement($data)) {
                // ✅ Notification pour TOUS les Direction, DAF et SuperAdmin de TOUS les stores
                try {
                    if (class_exists('App\Controllers\NotificationController')) {
                        $Stores = new Stores();
                        $allStores = $Stores->getActiveStore();
                        
                        $message = "💱 Nouveau recouvrement créé<br>" .
                                   "Montant: " . number_format($amount, 0, ',', ' ') . " Ar<br>" .
                                   "De: " . $send_mode . " → Vers: " . $get_mode . "<br>" .
                                   "Store: " . $this->returnStoreName($users['store_id']) . "<br>" .
                                   "Par: " . $fullname;
                        
                        // ✅ Notifier Direction, DAF et SuperAdmin de TOUS les stores
                        if (is_array($allStores) && count($allStores) > 0) {
                            foreach ($allStores as $store) {
                                // Notifier Direction
                                $Notification->createNotification(
                                    $message, 
                                    "Direction", 
                                    (int)$store['id'],
                                    'recouvrement'
                                );
                                
                                // Notifier DAF
                                $Notification->createNotification(
                                    $message, 
                                    "DAF", 
                                    (int)$store['id'],
                                    'recouvrement'
                                );
                                
                                // Notifier SuperAdmin
                                $Notification->createNotification(
                                    $message, 
                                    "SuperAdmin", 
                                    (int)$store['id'],
                                    'recouvrement'
                                );
                            }
                        }
                    }
                } catch (\Exception $e) {
                    log_message('error', 'Erreur notification createRecouvrement: ' . $e->getMessage());
                    // Continue même si la notification échoue
                }
                
                $response['success'] = true;
                $response['messages'] = 'Recouvrement créé avec succès<br>' .
                                       'Montant: ' . number_format($amount, 0, ',', ' ') . ' Ar<br>' .
                                       $send_mode . ' → ' . $get_mode . '<br>' .
                                       '<em>Notification envoyée à tous les Direction, DAF et SuperAdmin</em>';
            } else {
                $response['success'] = false;
                $response['messages'] = 'Erreur lors de la création du recouvrement.';
            }
        } else {
            // Validation failed, return error messages
            $response['success'] = false;
            $response['messages'] = $validation->getErrors();
        }
    
        return $this->response->setJSON($response);
    }

    public function updateRecouvrement($recouvrement_id)
    {
        $this->verifyRole('updateRecouvrement');

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

        // Load validation service
        $validation = \Config\Services::validation();

        // Set validation rules
        $validation->setRules([
            'product[]' => 'required'
        ]);

        $validationData = [
            'product[]' => $this->request->getPost('product[]')
        ];

        $Recouvrement = new Recouvrement();
        
        if ($this->request->getMethod() === 'post') {
            $data = [
                'recouvrement_montant' => (int) $this->request->getPost('recouvrement_montant_edit'),
                'recouvrement_date' => $this->request->getPost('recouvrement_date_edit')
            ];
            
            if ($Recouvrement->updateRecouvrement($recouvrement_id, $data)) {
                // ✅ Notification pour TOUS les Direction, DAF et SuperAdmin de TOUS les stores
                try {
                    if (class_exists('App\Controllers\NotificationController')) {
                        $Notification = new NotificationController();
                        $Stores = new Stores();
                        $allStores = $Stores->getActiveStore();
                        
                        $session = session();
                        $users = $session->get('user');
                        
                        $message = "✏️ Recouvrement modifié<br>" .
                                   "Nouveau montant: " . number_format($data['recouvrement_montant'], 0, ',', ' ') . " Ar<br>" .
                                   "Par: " . $users['firstname'] . ' ' . $users['lastname'];
                        
                        // ✅ Notifier Direction, DAF et SuperAdmin de TOUS les stores
                        if (is_array($allStores) && count($allStores) > 0) {
                            foreach ($allStores as $store) {
                                $Notification->createNotification(
                                    $message, 
                                    "Direction", 
                                    (int)$store['id'],
                                    'recouvrement'
                                );
                                
                                $Notification->createNotification(
                                    $message, 
                                    "DAF", 
                                    (int)$store['id'],
                                    'recouvrement'
                                );
                                
                                $Notification->createNotification(
                                    $message, 
                                    "SuperAdmin", 
                                    (int)$store['id'],
                                    'recouvrement'
                                );
                            }
                        }
                    }
                } catch (\Exception $e) {
                    log_message('error', 'Erreur notification updateRecouvrement: ' . $e->getMessage());
                }
                
                return $this->response->setJSON([
                    'success' => true,
                    'messages' => 'Recouvrement modifié avec succès !<br><em>Notification envoyée à tous les Direction, DAF et SuperAdmin</em>'
                ]);
            } else {
                return $this->response->setJSON([
                    'success' => false,
                    'messages' => 'Erreur lors de la modification du recouvrement.'
                ]);
            }
        }
    }

    public function fetchRecouvrementSingle($id)
    {
        // die(var_dump('hghjbhj'));
        if ($id) {
            $recouvrement = new Recouvrement();

            $data = $recouvrement->getRecouvrementSingle($id);
            echo json_encode($data);
        }
    }

    private function returnStoreName(int $id): string
    {
        $Stores = new Stores();
        $stor = $Stores->getActiveStore();
        $Storename = "";
        foreach ($stor as $key => $value) {
            if ($value['id'] == $id) {
                $Storename = $value['name'];
            }
        }
        return $Storename;
    }

    private function canMakeRecouvrement($send_mode, $get_mode, $amount): bool
{
    $orders = new Orders();
    $recouvrement = new Recouvrement();
    $sortieCaisse = new SortieCaisse();
    $avance = new Avance();

    // Récupérer les données actuelles
    $paymentDataOrders = $orders->getPaymentModes();
    $paymentDataAvance = $avance->getPaymentModesAvance();
    $totalRecouvrement = $recouvrement->getTotalRecouvrements();
    $total_sortie_caisse = $sortieCaisse->getTotalSortieCaisse();

    // === EXTRACTION DES SORTIES PAR MODE DE PAIEMENT ===
    $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;

    // === TOTAUX PAIEMENTS ORDERS ===
    $mv1_orders = isset($paymentDataOrders->total_mvola1) ? (float) $paymentDataOrders->total_mvola1 : 0;
    $mv2_orders = isset($paymentDataOrders->total_mvola2) ? (float) $paymentDataOrders->total_mvola2 : 0;
    $es1_orders = isset($paymentDataOrders->total_espece1) ? (float) $paymentDataOrders->total_espece1 : 0;
    $es2_orders = isset($paymentDataOrders->total_espece2) ? (float) $paymentDataOrders->total_espece2 : 0;
    $vb1_orders = isset($paymentDataOrders->total_virement_bancaire1) ? (float) $paymentDataOrders->total_virement_bancaire1 : 0;
    $vb2_orders = isset($paymentDataOrders->total_virement_bancaire2) ? (float) $paymentDataOrders->total_virement_bancaire2 : 0;

    // === TOTAUX PAIEMENTS AVANCES ===
    $mv_avances = isset($paymentDataAvance->total_mvola) ? (float) $paymentDataAvance->total_mvola : 0;
    $es_avances = isset($paymentDataAvance->total_espece) ? (float) $paymentDataAvance->total_espece : 0;
    $vb_avances = isset($paymentDataAvance->total_virement_bancaire) ? (float) $paymentDataAvance->total_virement_bancaire : 0;

    // === TOTAUX RECOUVREMENT ===
    $me = isset($totalRecouvrement->me) ? (float) $totalRecouvrement->me : 0;
    $bm = isset($totalRecouvrement->bm) ? (float) $totalRecouvrement->bm : 0;
    $be = isset($totalRecouvrement->be) ? (float) $totalRecouvrement->be : 0;
    $mb = isset($totalRecouvrement->mb) ? (float) $totalRecouvrement->mb : 0;

    // === CALCUL DES SOLDES ACTUELS ===
    $solde_mvola = ($mv1_orders + $mv2_orders + $mv_avances) - $me - $mb + $bm - $total_sortie_mvola;
    $solde_espece = ($es1_orders + $es2_orders + $es_avances) + $me + $be - $total_sortie_espece;
    $solde_banque = ($vb1_orders + $vb2_orders + $vb_avances) - $be - $bm + $mb - $total_sortie_virement;

    // === VÉRIFICATION EN FONCTION DU TYPE DE RECOUVREMENT ===
    switch ($send_mode) {
        case 'MVOLA':
            if ($get_mode === 'En espèce') {
                // MVOLA → Espèce : vérifier solde MVOLA
                return $solde_mvola >= $amount;
            } elseif ($get_mode === 'Virement Bancaire') {
                // MVOLA → Banque : vérifier solde MVOLA
                return $solde_mvola >= $amount;
            }
            break;

        case 'Virement Bancaire':
            if ($get_mode === 'MVOLA') {
                // Banque → MVOLA : vérifier solde banque
                return $solde_banque >= $amount;
            } elseif ($get_mode === 'En espèce') {
                // Banque → Espèce : vérifier solde banque
                return $solde_banque >= $amount;
            }
            break;
    }

    return false;
}

    public function fetchTotalRecouvrementData() {
        helper(['url', 'form']);
        $Recouvrement = new Recouvrement();
        $start_date = $this->request->getGet('start_date');
        $end_date = $this->request->getGet('end_date');
        if ($start_date && $end_date) {
            
        // Initialiser les variables pour DataTables
        $draw = intval($this->request->getVar('draw'));
        $session = session();
        $users = $session->get('user');
        if($users['group_name'] === "Caissière"){
            $data = $Recouvrement->getTotalRecouvrements($users['id'] );

            $result = [
                "draw" => $draw,
                "recordsTotal" => 1,
                "recordsFiltered" => 1,
                "data" => []
            ];

            $totalRecouvrement = $Recouvrement->getTotalRecouvrements($users['id'], $start_date, $end_date );
            $total_recouvrement_me = $totalRecouvrement->me;
            $total_recouvrement_bm = $totalRecouvrement->bm;
            $total_recouvrement_be = $totalRecouvrement->be;
            $total_recouvrement_mb = $totalRecouvrement->mb;
            $total_recouvrement = $total_recouvrement_me + $total_recouvrement_me + $total_recouvrement_be + $total_recouvrement_mb; 
                $data = [
                    number_format($total_recouvrement_me,0,'.',' '),
                    number_format($total_recouvrement_bm,0,'.',' '),
                    number_format($total_recouvrement_be,0,'.',' '),
                    number_format($total_recouvrement_mb,0,'.',' '),
                    number_format($total_recouvrement,0,'.',' '),
                ];
            }
            return $this->response->setJSON($result);
        }
        // Initialiser les variables pour DataTables
        $draw = intval($this->request->getVar('draw'));
        $session = session();
        $users = $session->get('user');
        if($users['group_name'] === "Caissière"){
            $data = $Recouvrement->getTotalRecouvrements($users['id'] );

            $result = [
                "draw" => $draw,
                "recordsTotal" => 1,
                "recordsFiltered" => 1,
                "data" => []
            ];
            $totalRecouvrement = $Recouvrement->getTotalRecouvrements($users['id'] );
            $total_recouvrement_me = $totalRecouvrement->me;
            $total_recouvrement_bm = $totalRecouvrement->bm;
            $total_recouvrement_be = $totalRecouvrement->be;
            $total_recouvrement_mb = $totalRecouvrement->mb;
            $total_recouvrement = $total_recouvrement_me + $total_recouvrement_me + $total_recouvrement_be + $total_recouvrement_mb; 
                $data = [
                    number_format($total_recouvrement_me,0,'.',' '),
                    number_format($total_recouvrement_bm,0,'.',' '),
                    number_format($total_recouvrement_be,0,'.',' '),
                    number_format($total_recouvrement_mb,0,'.',' '),
                    number_format($total_recouvrement,0,'.',' '),
                ];
            }
            return $this->response->setJSON($result);
    }
}
