<?php

namespace App\Controllers;

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

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

    private $mapping = [
        // ----- 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');
    $result = [
        "draw"            => $draw,
        "recordsTotal"    => $totalRecords,
        "recordsFiltered" => $totalRecords,
        "data"            => []
    ];

    foreach ($data as $key => $value) {
        $buttons = '';
        if (in_array('updateSortieCaisse', $this->permission) && $value['id_sortie'] == $users['id']) {
            $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>';
        }
        if (in_array('validateSortieCaisse', $this->permission)) {
            $buttons .= '<button type="button" class="btn btn-default" onclick="validateFunc(' . $value['id_sortie'] . ')"><i class="fa fa-check-circle"></i></button>';
        }
        // D'éventuelles autres actions peuvent être ajoutées ici
        $session = session();
        $users = $session->get('user');
        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
            ];
        }
        elseif ($users["group_name"] === "Direction" || $users["group_name"] === "Conseil") {
            $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
            ];
        }
        
    }
    return $this->response->setJSON($result);
}

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');
    $result = [
        "draw"            => $draw,
        "recordsTotal"    => $totalRecords,
        "recordsFiltered" => $totalRecords,
        "data"            => []
    ];

    foreach ($data as $key => $value) {
        $buttons = '';
        if (in_array('updateSortieCaisse', $this->permission) && $value['id_sortie'] == $users['id']) {
            $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>';
        }
        if (in_array('validateSortieCaisse', $this->permission)) {
            $buttons .= '<button type="button" class="btn btn-default" onclick="validateFunc(' . $value['id_sortie'] . ')"><i class="fa fa-check-circle"></i></button>';
        }
        // D'éventuelles autres actions peuvent être ajoutées ici
        $session = session();
        $users = $session->get('user');
        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'],
                $buttons
            ];
        }
        elseif ($users["group_name"] === "Direction" || $users["group_name"] === "Conseil") {
            $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
            ];
        }
        
    }
    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');

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

        $validation = \Config\Services::validation();

        $validation->setRules([
            'montant_retire' => 'required',
            'motif' => 'required',
        ]);
        

        $validationData = [
            'montant_retire'          => $this->request->getPost('montant_retire'),
            'motif'                   => $this->request->getPost('motif_select'),
        ];
        

        // Set validation rules
        $orders = new Orders();
        $Recouvrement = new Recouvrement();
        $paymentData = $orders->getPaymentModes();
        $sortieCaisse = new SortieCaisse();
        $total_sortie_caisse = $sortieCaisse->getTotalSortieCaisse();
        $total_sortie_caisse1= $total_sortie_caisse->mr;
        $totalRecouvrement = $Recouvrement->getTotalRecouvrements();
        //me MVOLA => ESPECE
        //bm BANQUE => MVOLA
        //be BANQUE => ESPECE
        //mb MVOLA => BANQUE
        $total_recouvrement_me = $totalRecouvrement->me;
        $total_recouvrement_bm = $totalRecouvrement->bm;
        $total_recouvrement_be = $totalRecouvrement->be;
        $total_recouvrement_mb = $totalRecouvrement->mb;

        // Initialisation des totaux avec 0 au cas où il n'y aurait pas de données
        $total = isset($paymentData->total) ? $paymentData->total : 0;
        $total_espece1 = isset($paymentData->total_espece1) ? $paymentData->total_espece1 : 0;
        $total_espece2 = isset($paymentData->total_espece2) ? $paymentData->total_espece2 : 0;

        $total_espece = $total_espece1 + $total_espece2;
        $total_espece1 = $total_espece + $total_recouvrement_me + $total_recouvrement_be - $total_sortie_caisse1;




        $Notification = new NotificationController();
        // $recouvrement_id = $this->request->getPost('recouvrement_id');
        $session = session();
        $users = $session->get('user');
        if ($users && isset($users['firstname'], $users['lastname'])) {
            $fullname = $users['firstname'] . ' ' . $users['lastname'];
        }
        
        // Motif venant du select ou du champ "Autre"
        $motif = $this->request->getPost('motif_select');
        $source_fond ='';
        $initiateur_demande = '';
        $binaryData = "";
        $mimeType = "";
        if (isset($mapping[$motif])) {
            $source_fond        = $this->mapping[$motif]['source_fond'];
            $initiateur_demande = $this->mapping[$motif]['initiateur_demande'];
        }

        $file = $this->request->getFile('sortie_preuve');


        if (
            $file
            && $file->isValid()            
            && $file->getError() !== UPLOAD_ERR_NO_FILE
            && ($tmpName = $file->getTempName()) 
            && file_exists($tmpName)        
        ) {
            
            $binaryData = file_get_contents($tmpName);
            
            $mimeType   = $file->getClientMimeType();
            
        
        }


           

        if ($validation->run($validationData)) {
            $data = [
                'montant_retire'          => $this->request->getPost('montant_retire'),
                'date_retrait'            => date('Y-m-d'),
                'motif'                   => $this->request->getPost('motif_select'),
                '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'),
                'source_fond'             => $source_fond,
                'initiateur_demande'      => $initiateur_demande,
                'store_id'                => $users['store_id'],
                'preuve_achat'            => $binaryData,
                'mime_type'               => $mimeType,
                'statut'                  => "En attente",
                'user_id'                => $users['id'],
                'sortie_personnel'        => $fullname
                ];
            
            
            if ((int)$this->request->getPost('montant_retire') > $total_espece1) {
                if($sortieCaisse->addSortieCaisse($data)){
                    $Notification->createNotification("Une demande décaissement a été enregistré", "Conseil", (int)$users['store_id'], 'sortieCaisse');
                    $response['success'] = true;
                    $response['messages'] = 'Décaissement enregistré avec succès';
                }
                else {
                    return $this->response->setJSON([
                        'success' => false,
                        'messages' => 'Erreur lors de la modification du décaissement. Veuillez réessayer.'
                    ]);
                }
                
            } else {
                $response['success'] = false;
                $response['messages'] = 'Décaissements échoués — fonds en espèce insuffisants';
            }
        } else {
            // Validation failed, return error messages
            $response['success'] = false;
            $response['messages'] = $validation->getErrors();
        }

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



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

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

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


        $SortieCaisse = new SortieCaisse();
        $orders = new Orders();
        $Recouvrement = new Recouvrement();
        $paymentData = $orders->getPaymentModes();
        $sortieCaisse = new SortieCaisse();
        $total_sortie_caisse = $sortieCaisse->getTotalSortieCaisse();
        $total_sortie_caisse1= $total_sortie_caisse->mr;
        $totalRecouvrement = $Recouvrement->getTotalRecouvrements();

        $total_recouvrement_me = $totalRecouvrement->me;
        $total_recouvrement_bm = $totalRecouvrement->bm;
        $total_recouvrement_be = $totalRecouvrement->be;
        $total_recouvrement_mb = $totalRecouvrement->mb;

        // Initialisation des totaux avec 0 au cas où il n'y aurait pas de données
        $total = isset($paymentData->total) ? $paymentData->total : 0;
        $total_espece1 = isset($paymentData->total_espece1) ? $paymentData->total_espece1 : 0;
        $total_espece2 = isset($paymentData->total_espece2) ? $paymentData->total_espece2 : 0;

        $total_espece = $total_espece1 + $total_espece2;
        $total_espece1 = $total_espece + $total_recouvrement_me + $total_recouvrement_be - $total_sortie_caisse1;




        
        if ($this->request->getMethod() === 'post') {
            $session = session();
            $users = $session->get('user');
            if ($users && isset($users['firstname'], $users['lastname'])) {
                $fullname = $users['firstname'] . ' ' . $users['lastname'];
            }

             // Motif venant du select ou du champ "Autre"
            $motif = $this->request->getPost('motif_select');

            
            if (isset($mapping[$motif])) {
                $source_fond        = $this->mapping[$motif]['source_fond'];
                $initiateur_demande = $this->mapping[$motif]['initiateur_demande'];
            } 

            // Récupération de l'objet UploadedFile
            $file = $this->request->getFile('sortie_preuve_edit');

            if ($file && $file->isValid() && ! $file->hasMoved()) {
                // Récupère le chemin temporaire
                $tmpName = $file->getTempName();
                // Lit tout le contenu binaire
                $binaryData = file_get_contents($tmpName);
                // Récupère le Mime-Type pour le stocker si besoin
                $mimeType   = $file->getClientMimeType();
            } else {
                $binaryData = null;
                $mimeType   = null;
            }
            $data = [
                'montant_retire'          => $this->request->getPost('montant_retire_edit'),
                'date_retrait'           => date('Y-m-d'),
                'motif'                   => $this->request->getPost('motif_select'),
                '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'        => $fullname,
                'source_fond'             => $source_fond,
                'initiateur_demande'      => $initiateur_demande,
                'store_id'                => $users['store_id'],
                'preuve_achat'            => $binaryData,
                'mime_type'               => $mimeType
            ];
            
            
            $Notification = new NotificationController();
            if ((int) $this->request->getPost('sortie_montant_edit') > $total_espece1) {
                if($SortieCaisse->updateSortieCaisse($id_sortie, $data)){
                    return $this->response->setJSON([
                        'success' => true,
                        'messages' => 'Décaissement modifié  avec succès !'
                    ]);
                }
                else {
                    return $this->response->setJSON([
                        'success' => false,
                        'messages' => 'Erreur lors de la modification du décaissement. Veuillez réessayer.'
                    ]);
                }
                
               
            } else {
                return $this->response->setJSON([
                    'success' => false,
                    'messages' => 'Décaissements échoués — fonds en espèce insuffisants'
                ]);
            }
        }
    }

    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) && $this->request->getPost('statut') === "Valider"){
                $Notification->createNotification("Décaissement validé avec succès", "Caissière", (int)$users["store_id"], 'sortieCaisse');
                return $this->response->setJSON([
                    'success' => true,
                    'messages' => 'Décaissement modifié  avec succès !'
                ]);
            }
            elseif($SortieCaisse->updateSortieCaisse($id_sortie, $data) &&  $this->request->getPost('statut') === "Refuser"){
                $Notification->createNotification("un décaissement a été réfusé", "Caissière", (int)$users["store_id"], 'sortieCaisse');
                return $this->response->setJSON([
                    'success' => true,
                    'messages' => 'Décaissement modifié  avec succès !'
                ]);
            }
            elseif($SortieCaisse->updateSortieCaisse($id_sortie, $data) && $this->request->getPost('statut') === "En attente"){
                $Notification->createNotification("Décaissement mis en attente", "Caissière", (int)$users["store_id"], 'sortieCaisse');
                return $this->response->setJSON([
                    'success' => true,
                    'messages' => 'Décaissement modifié  avec succès !'
                ]);
            }
            else {
                return $this->response->setJSON([
                    'success' => false,
                    'messages' => 'Erreur lors de la modification du décaissement. Veuillez réessayer.'
                ]);
            }   
        } 
    }
    
}
