<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Cashboxes extends CI_Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->load->library('auth_lib');
        $this->load->library('form_validation');
        $this->load->model('Cashbox_model');
        $this->load->helper(['url', 'form']);
        $this->auth_lib->require_login();
    }

    // ===============================================================
    // CAISSES - LISTE & DÉTAILS
    // ===============================================================

    /**
     * Vue d'ensemble des caisses (position de trésorerie)
     */
    public function index()
    {
        $this->auth_lib->require_permission('cashbox_view');

        // Filtrer selon les droits d'accès de l'utilisateur
        $is_manager  = $this->auth_lib->is_manager_or_admin();
        $location_id = $this->auth_lib->location_id();

        $cashboxes = $this->Cashbox_model->get_accessible($location_id, $is_manager);

        // Total = seulement sur les caisses visibles
        $total = 0;
        foreach ($cashboxes as $cb) {
            $total += (float) $cb->current_balance;
        }

        $data = [
            'title'          => 'Gestion des Caisses',
            'cashboxes'      => $cashboxes,
            'total_balance'  => $total,
            'is_manager'     => $is_manager,
        ];

        $this->load->view('templates/header', $data);
        $this->load->view('cashboxes/index', $data);
        $this->load->view('templates/footer');
    }

    /**
     * Ajuster le solde d'une caisse (initialisation / correction)
     * Réservé à l'Operation Manager et Admin
     */
    public function adjust_balance($id)
    {
        $this->auth_lib->require_permission('cashbox_manage');

        $cashbox = $this->Cashbox_model->get($id);
        if ( ! $cashbox) show_404();

        $data = [
            'title'   => 'Ajuster le solde — ' . $cashbox->name,
            'cashbox' => $cashbox,
        ];

        if ($this->input->method() === 'post') {
            $this->form_validation->set_rules('new_balance', 'Nouveau solde', 'required|numeric');
            $this->form_validation->set_rules('reason', 'Motif', 'required|trim|min_length[5]');

            if ($this->form_validation->run() === TRUE) {
                $old_balance = $cashbox->current_balance;
                $new_balance = $this->input->post('new_balance');
                $reason      = $this->input->post('reason', TRUE);

                $this->Cashbox_model->set_balance($id, $new_balance);

                $this->auth_lib->log_action(
                    $this->auth_lib->user_id(), 'balance_adjusted', 'cashboxes', $id,
                    $cashbox->code . ' : ' . number_format($old_balance) . ' → ' . number_format($new_balance) . ' KMF | ' . $reason
                );

                $this->session->set_flashdata('success', 
                    'Solde de ' . $cashbox->name . ' ajusté à ' . number_format($new_balance, 0, ',', ' ') . ' KMF.');
                redirect('cashboxes');
            }
        }

        $this->load->view('templates/header', $data);
        $this->load->view('cashboxes/adjust_balance', $data);
        $this->load->view('templates/footer');
    }

    /**
     * Détail d'une caisse avec historique des mouvements
     */
    public function view($id)
    {
        $this->auth_lib->require_permission('cashbox_view');

        $cashbox = $this->Cashbox_model->get($id);
        if ( ! $cashbox) show_404();

        // Vérifier accès localisation
        if ( ! $this->auth_lib->can_access_location($cashbox->location_id)) {
            $this->session->set_flashdata('error', 'Accès refusé à cette caisse.');
            redirect('cashboxes');
        }

        $date_from = $this->input->get('date_from') ?: date('Y-m-01');
        $date_to   = $this->input->get('date_to')   ?: date('Y-m-d');

        $data = [
            'title'      => $cashbox->name,
            'cashbox'    => $cashbox,
            'movements'  => $this->Cashbox_model->get_movements($id, $date_from, $date_to, 100),
            'last_closing'=> $this->Cashbox_model->get_last_closing($id),
            'date_from'  => $date_from,
            'date_to'    => $date_to,
        ];

        $this->load->view('templates/header', $data);
        $this->load->view('cashboxes/view', $data);
        $this->load->view('templates/footer');
    }

    // ===============================================================
    // CLÔTURES DE CAISSE
    // ===============================================================

    /**
     * Liste des clôtures
     */
    public function closings()
    {
        $this->auth_lib->require_permission('cashbox_view');

        $filters = [
            'cashbox_id' => $this->input->get('cashbox_id'),
            'status'     => $this->input->get('status'),
            'date_from'  => $this->input->get('date_from'),
            'date_to'    => $this->input->get('date_to'),
        ];

        $data = [
            'title'     => 'Clôtures de Caisse',
            'closings'  => $this->Cashbox_model->get_closings($filters, 30),
            'cashboxes' => $this->Cashbox_model->get_all(['is_active' => 1]),
            'filters'   => $filters,
        ];

        $this->load->view('templates/header', $data);
        $this->load->view('cashboxes/closings', $data);
        $this->load->view('templates/footer');
    }

    /**
     * Créer une clôture de caisse
     */
    public function close($cashbox_id = null)
    {
        $this->auth_lib->require_permission('cashbox_close');

        $cashboxes = $this->Cashbox_model->get_accessible(
            $this->auth_lib->location_id(),
            $this->auth_lib->is_manager_or_admin()
        );

        // Si cashbox_id passé, pré-remplir
        $selected_cashbox = null;
        $movements = null;
        if ($cashbox_id) {
            $selected_cashbox = $this->Cashbox_model->get($cashbox_id);
            if ( ! $selected_cashbox) show_404();
        }

        $data = [
            'title'             => 'Nouvelle Clôture de Caisse',
            'cashboxes'         => $cashboxes,
            'selected_cashbox'  => $selected_cashbox,
        ];

        if ($this->input->method() === 'post') {
            $this->form_validation->set_rules('cashbox_id', 'Caisse', 'required|integer');
            $this->form_validation->set_rules('period_start', 'Début période', 'required');
            $this->form_validation->set_rules('period_end', 'Fin période', 'required');
            $this->form_validation->set_rules('opening_balance', 'Solde initial', 'required|numeric');
            $this->form_validation->set_rules('closing_balance', 'Solde final', 'required|numeric');

            if ($this->form_validation->run() === TRUE) {
                $cb_id       = $this->input->post('cashbox_id');
                $period_start = $this->input->post('period_start');
                $period_end   = $this->input->post('period_end');

                // Calculer les mouvements automatiquement
                $mvt = $this->Cashbox_model->get_period_movements($cb_id, $period_start, $period_end);

                $closing_data = [
                    'cashbox_id'      => $cb_id,
                    'period_start'    => $period_start,
                    'period_end'      => $period_end,
                    'opening_balance' => $this->input->post('opening_balance'),
                    'total_in'        => $mvt['transfers_in'],
                    'total_out'       => $mvt['expenses'] + $mvt['transfers_out'],
                    'closing_balance' => $this->input->post('closing_balance'),
                    'physical_count'  => $this->input->post('physical_count') ?: null,
                    'difference'      => $this->input->post('physical_count')
                        ? $this->input->post('physical_count') - $this->input->post('closing_balance')
                        : null,
                    'notes'           => $this->input->post('notes', TRUE),
                    'closed_by'       => $this->auth_lib->user_id(),
                    'status'          => 'draft',
                ];

                $new_id = $this->Cashbox_model->create_closing($closing_data);

                $this->auth_lib->log_action(
                    $this->auth_lib->user_id(), 'closing_created', 'cashboxes', $new_id
                );

                $this->session->set_flashdata('success', 'Clôture créée avec succès.');
                redirect('cashboxes/closings');
            }
        }

        $this->load->view('templates/header', $data);
        $this->load->view('cashboxes/close_form', $data);
        $this->load->view('templates/footer');
    }

    /**
     * Confirmer une clôture (passage draft → confirmed)
     */
    public function confirm_closing($id)
    {
        $this->auth_lib->require_permission('cashbox_close');

        $closing = $this->Cashbox_model->get_closing($id);
        if ( ! $closing || $closing->status !== 'draft') {
            $this->session->set_flashdata('error', 'Clôture introuvable ou déjà confirmée.');
            redirect('cashboxes/closings');
        }

        $this->Cashbox_model->update_closing($id, ['status' => 'confirmed']);

        $this->auth_lib->log_action(
            $this->auth_lib->user_id(), 'closing_confirmed', 'cashboxes', $id
        );

        $this->session->set_flashdata('success', 'Clôture confirmée.');
        redirect('cashboxes/closings');
    }

    /**
     * Voir le détail d'une clôture
     */
    public function closing_detail($id)
    {
        $this->auth_lib->require_permission('cashbox_view');

        $closing = $this->Cashbox_model->get_closing($id);
        if ( ! $closing) show_404();

        $data = [
            'title'   => 'Clôture #' . $id . ' — ' . $closing->cashbox_name,
            'closing' => $closing,
        ];

        $this->load->view('templates/header', $data);
        $this->load->view('cashboxes/closing_detail', $data);
        $this->load->view('templates/footer');
    }
}
