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

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

    /**
     * Liste des demandes
     */
    public function index()
    {
        $this->auth_lib->require_permission('request_view');

        $this->load->model('User_model');

        $filters = [
            'status'          => $this->input->get('status'),
            'location_id'     => $this->input->get('location_id'),
            'missing_expense' => $this->input->get('missing_expense'),
            'missing_invoice' => $this->input->get('missing_invoice'),
        ];

        // Agents locaux : filtrer par leur localisation
        if ( ! $this->auth_lib->is_manager_or_admin() && $this->auth_lib->location_id()) {
            $filters['user_location_id'] = $this->auth_lib->location_id();
        }

        $page   = max(1, (int) $this->input->get('page'));
        $limit  = 20;
        $offset = ($page - 1) * $limit;

        $data = [
            'title'      => 'Demandes de Dépenses',
            'requests'   => $this->Request_model->get_list($filters, $limit, $offset),
            'total'      => $this->Request_model->count_list($filters),
            'locations'  => $this->User_model->get_locations(),
            'filters'    => $filters,
            'page'       => $page,
            'limit'      => $limit,
        ];

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

    /**
     * Créer une demande
     */
    public function create()
    {
        $this->auth_lib->require_permission('request_create');

        $this->load->model('User_model');

        // Catégories de type "request" uniquement
        $categories = $this->Expense_model->get_categories('request');

        $data = [
            'title'      => 'Nouvelle Demande de Dépense',
            'categories' => $categories,
            'locations'  => $this->User_model->get_locations(),
            'reference'  => $this->Request_model->next_reference(),
        ];

        if ($this->input->method() === 'post') {
            $this->form_validation->set_rules('category_id', 'Catégorie', 'required|integer');
            $this->form_validation->set_rules('location_id', 'Localisation', 'required|integer');
            $this->form_validation->set_rules('description', 'Description', 'required|trim|min_length[5]');
            $this->form_validation->set_rules('estimated_amount', 'Montant estimé', 'required|numeric|greater_than[0]');

            if ($this->form_validation->run() === TRUE) {
                $request_data = [
                    'reference'        => $this->Request_model->next_reference(),
                    'request_date'     => date('Y-m-d'),
                    'category_id'      => $this->input->post('category_id'),
                    'location_id'      => $this->input->post('location_id'),
                    'description'      => $this->input->post('description', TRUE),
                    'supplier'         => $this->input->post('supplier', TRUE) ?: null,
                    'estimated_amount' => $this->input->post('estimated_amount'),
                    'currency'         => 'KMF',
                    'status'           => 'pending',
                    'requested_by'     => $this->auth_lib->user_id(),
                ];

                $new_id = $this->Request_model->create($request_data);

                $this->auth_lib->log_action(
                    $this->auth_lib->user_id(), 'request_created', 'requests', $new_id,
                    $request_data['reference'] . ' | ' . number_format($request_data['estimated_amount']) . ' KMF'
                );

                $this->session->set_flashdata('success', 
                    'Demande ' . $request_data['reference'] . ' soumise. En attente d\'approbation.');
                redirect('requests/view/' . $new_id);
            }
        }

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

    /**
     * Voir le détail d'une demande
     */
    public function view($id)
    {
        $this->auth_lib->require_permission('request_view');

        $request = $this->Request_model->get($id);
        if ( ! $request) show_404();

        if ( ! $this->auth_lib->can_access_location($request->location_id)) {
            $this->session->set_flashdata('error', 'Accès refusé.');
            redirect('requests');
        }

        // Chercher la dépense liée si elle existe
        $linked_expense = null;
        $linked_expense = $this->db
            ->select('expenses.id, expenses.expense_id, expenses.amount, expenses.status, 
                      expenses.invoice_path, expenses.validated_by, expenses.expense_date,
                      cashboxes.name AS cashbox_name')
            ->join('cashboxes', 'cashboxes.id = expenses.cashbox_id', 'left')
            ->where('expenses.request_id', $id)
            ->get('expenses')
            ->row();

        $data = [
            'title'          => 'Demande ' . $request->reference,
            'request'        => $request,
            'linked_expense' => $linked_expense,
        ];

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

    /**
     * Modifier une demande (seulement si pending)
     */
    public function edit($id)
    {
        $this->auth_lib->require_permission('request_create');

        $request = $this->Request_model->get($id);
        if ( ! $request) show_404();

        if ($request->status !== 'pending') {
            $this->session->set_flashdata('error', 'Cette demande ne peut plus être modifiée.');
            redirect('requests/view/' . $id);
        }

        // Seul le demandeur ou un manager peut modifier
        if ($request->requested_by != $this->auth_lib->user_id() && ! $this->auth_lib->is_manager_or_admin()) {
            $this->session->set_flashdata('error', 'Vous ne pouvez modifier que vos propres demandes.');
            redirect('requests/view/' . $id);
        }

        $this->load->model('User_model');

        $data = [
            'title'      => 'Modifier ' . $request->reference,
            'request'    => $request,
            'categories' => $this->Expense_model->get_categories('request'),
            'locations'  => $this->User_model->get_locations(),
        ];

        if ($this->input->method() === 'post') {
            $this->form_validation->set_rules('category_id', 'Catégorie', 'required|integer');
            $this->form_validation->set_rules('location_id', 'Localisation', 'required|integer');
            $this->form_validation->set_rules('description', 'Description', 'required|trim|min_length[5]');
            $this->form_validation->set_rules('estimated_amount', 'Montant estimé', 'required|numeric|greater_than[0]');

            if ($this->form_validation->run() === TRUE) {
                $update_data = [
                    'category_id'      => $this->input->post('category_id'),
                    'location_id'      => $this->input->post('location_id'),
                    'description'      => $this->input->post('description', TRUE),
                    'supplier'         => $this->input->post('supplier', TRUE) ?: null,
                    'estimated_amount' => $this->input->post('estimated_amount'),
                ];

                $this->Request_model->update($id, $update_data);

                $this->auth_lib->log_action(
                    $this->auth_lib->user_id(), 'request_updated', 'requests', $id, $request->reference
                );

                $this->session->set_flashdata('success', 'Demande modifiée.');
                redirect('requests/view/' . $id);
            }
        }

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

    /**
     * Approuver une demande
     */
    public function approve($id)
    {
        $this->auth_lib->require_permission('request_approve');

        $request = $this->Request_model->get($id);
        if ( ! $request || $request->status !== 'pending') {
            $this->session->set_flashdata('error', 'Demande introuvable ou déjà traitée.');
            redirect('requests');
        }

        $this->Request_model->update($id, [
            'status'      => 'approved',
            'approved_by' => $this->auth_lib->user_id(),
            'approved_at' => date('Y-m-d H:i:s'),
        ]);

        $this->auth_lib->log_action(
            $this->auth_lib->user_id(), 'request_approved', 'requests', $id,
            $request->reference . ' | ' . number_format($request->estimated_amount) . ' KMF'
        );

        $this->session->set_flashdata('success', 
            'Demande ' . $request->reference . ' approuvée. Elle peut maintenant être liée à une dépense.');
        redirect('requests/view/' . $id);
    }

    /**
     * Rejeter une demande
     */
    public function reject($id)
    {
        $this->auth_lib->require_permission('request_approve');

        $request = $this->Request_model->get($id);
        if ( ! $request || $request->status !== 'pending') {
            $this->session->set_flashdata('error', 'Demande introuvable ou déjà traitée.');
            redirect('requests');
        }

        $reason = $this->input->post('rejection_reason', TRUE);
        if (empty($reason)) {
            $this->session->set_flashdata('error', 'Veuillez indiquer un motif de rejet.');
            redirect('requests/view/' . $id);
        }

        $this->Request_model->update($id, [
            'status'           => 'rejected',
            'approved_by'      => $this->auth_lib->user_id(),
            'approved_at'      => date('Y-m-d H:i:s'),
            'rejection_reason' => $reason,
        ]);

        $this->auth_lib->log_action(
            $this->auth_lib->user_id(), 'request_rejected', 'requests', $id,
            $request->reference . ' | Motif: ' . $reason
        );

        $this->session->set_flashdata('success', 'Demande rejetée.');
        redirect('requests/view/' . $id);
    }
}
