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

class CajaChica extends MY_Controller {

    public function __construct() {
        parent::__construct();
        $this->load->model('finanzas/CajaChica_model');
        $this->load->model('configuracion/Empresa_model');
        $this->load->helper('numero');
    }

    // -------------------------------------------------------
    // INDEX — listado de cajas
    // -------------------------------------------------------
    public function index() {
        $this->validar_permiso('caja_chica_ver');

        $data['cajas'] = $this->CajaChica_model->listar();
        $this->layout('finanzas/caja_chica/index', $data);
    }

    // -------------------------------------------------------
    // APERTURA — formulario
    // -------------------------------------------------------
    public function apertura() {
        $this->validar_permiso('caja_chica_apertura');

        // Verificar que no haya una caja abierta
        $cajaAbierta = $this->CajaChica_model->obtener_caja_abierta();
        if ($cajaAbierta) {
            $this->session->set_flashdata('error', 'Ya existe una caja abierta. Debe cerrarla antes de abrir una nueva.');
            redirect('finanzas/caja_chica');
        }

        $data['monedas']       = $this->CajaChica_model->listar_monedas();
        $data['responsables']  = $this->CajaChica_model->listar_responsables();
        $data['ultima_caja']   = $this->CajaChica_model->obtener_ultima_caja();
        $this->layout('finanzas/caja_chica/apertura', $data);
    }

    // -------------------------------------------------------
    // STORE APERTURA
    // -------------------------------------------------------
    public function store_apertura() {
        $this->validar_permiso('caja_chica_apertura');

        $this->form_validation->set_rules('moneda_id',      'Moneda',       'required');
        $this->form_validation->set_rules('monto_inicial',  'Monto inicial','required|numeric');
        $this->form_validation->set_rules('fecha_apertura', 'Fecha',        'required');

        if ($this->form_validation->run() == FALSE) {
            return $this->apertura();
        }

        $cajaAbierta = $this->CajaChica_model->obtener_caja_abierta();
        if ($cajaAbierta) {
            $this->session->set_flashdata('error', 'Ya existe una caja abierta.');
            redirect('finanzas/caja_chica');
        }

        $moneda_id      = (int)$this->input->post('moneda_id', TRUE);
        $responsable_id = (int)$this->input->post('responsable_id', TRUE) ?: NULL;
        $monto_inicial  = (float)$this->input->post('monto_inicial', TRUE);
        $fecha_apertura = $this->input->post('fecha_apertura', TRUE);
        $observacion    = $this->input->post('observacion', TRUE);

        // Saldo anterior de la última caja cerrada
        $ultimaCaja    = $this->CajaChica_model->obtener_ultima_caja();
        $saldoAnterior = $ultimaCaja ? (float)$ultimaCaja->monto_actual : 0.00;

        // Estado ABIERTA
        $estadoAbierta = $this->CajaChica_model->obtener_estado('CAJA_CHICA', 'ABT');

        $this->db->trans_start();

        // 1. Insertar cabecera
        $cajId = $this->CajaChica_model->insertar_caja([
            'moneda_id'        => $moneda_id,
            'responsable_id'   => $responsable_id,
            'estado_id'        => $estadoAbierta->id,
            'monto_inicial'    => $monto_inicial,
            'monto_actual'     => $monto_inicial,
            'saldo_anterior'   => $saldoAnterior,
            'caja_anterior_id' => $ultimaCaja ? $ultimaCaja->id : NULL,
            'fecha_apertura'   => $fecha_apertura,
            'observacion'      => $observacion,
            'created_by'       => $this->session->userdata('id'),
            'created_at'       => date('Y-m-d H:i:s'),
        ]);

        // 2. Si hay saldo anterior, registrar movimiento APERTURA
        if ($saldoAnterior > 0) {
            $this->CajaChica_model->insertar_movimiento([
                'caja_id'    => $cajId,
                'moneda_id'  => $moneda_id,
                'tipo'       => 'I',
                'origen'     => 'APERTURA',
                'fecha'      => $fecha_apertura,
                'monto'      => $saldoAnterior,
                'concepto'   => 'Saldo trasladado de caja anterior #' . ($ultimaCaja ? $ultimaCaja->id : ''),
                'created_by' => $this->session->userdata('id'),
                'created_at' => date('Y-m-d H:i:s'),
            ]);
        }

        // 3. Si el monto inicial > saldo anterior, registrar la diferencia como ingreso adicional
        $montoAdicional = $monto_inicial - $saldoAnterior;
        if ($montoAdicional > 0) {
            $banco_cuenta_id   = (int)$this->input->post('banco_cuenta_id', TRUE) ?: NULL;
            $banco_nro_operacion = $this->input->post('banco_nro_operacion', TRUE);

            $this->CajaChica_model->insertar_movimiento([
                'caja_id'            => $cajId,
                'moneda_id'          => $moneda_id,
                'tipo'               => 'I',
                'origen'             => 'BANCO',
                'fecha'              => $fecha_apertura,
                'monto'              => $montoAdicional,
                'concepto'           => 'Ingreso inicial de apertura',
                'banco_cuenta_id'    => $banco_cuenta_id,
                'banco_nro_operacion'=> $banco_nro_operacion ?: NULL,
                'created_by'         => $this->session->userdata('id'),
                'created_at'         => date('Y-m-d H:i:s'),
            ]);
        }

        $this->db->trans_complete();

        if ($this->db->trans_status() === FALSE) {
            $this->session->set_flashdata('error', 'Error al abrir la caja. Intente nuevamente.');
            redirect('finanzas/caja_chica');
        }

        $this->session->set_flashdata('success', 'Caja abierta correctamente.');
        redirect('finanzas/caja_chica/ver/' . $cajId);
    }

    // -------------------------------------------------------
    // VER — detalle de la caja + movimientos
    // -------------------------------------------------------
    public function ver($id) {
        $this->validar_permiso('caja_chica_ver');

        $caja = $this->CajaChica_model->obtener_completo($id);
        if (!$caja) show_404();

        $data['caja']        = $caja;
        $data['movimientos'] = $this->CajaChica_model->listar_movimientos($id);
        $data['monedas']     = $this->CajaChica_model->listar_monedas();
        $data['bancos_cuentas'] = $this->CajaChica_model->listar_bancos_cuentas();
        $data['resumen']     = $this->CajaChica_model->obtener_resumen($id);
        $this->layout('finanzas/caja_chica/ver', $data);
    }

    // -------------------------------------------------------
    // STORE MOVIMIENTO — ingreso o egreso AJAX
    // -------------------------------------------------------
    public function store_movimiento() {
        $this->validar_permiso('caja_chica_movimiento');

        if (!$this->input->is_ajax_request()) {
            show_404();
        }

        $caja_id = (int)$this->input->post('caja_id', TRUE);
        $tipo    = $this->input->post('tipo', TRUE);  // I o E
        $origen  = $this->input->post('origen', TRUE);
        $monto   = (float)$this->input->post('monto', TRUE);
        $fecha   = $this->input->post('fecha', TRUE);
        $concepto= $this->input->post('concepto', TRUE);

        // Validaciones básicas
        if (!$caja_id || !in_array($tipo, ['I','E']) || $monto <= 0 || empty($concepto)) {
            echo json_encode(['status' => false, 'msg' => 'Datos incompletos o inválidos.']);
            return;
        }

        $caja = $this->CajaChica_model->obtener_completo($caja_id);
        if (!$caja || $caja->estado_codigo !== 'ABT') {
            echo json_encode(['status' => false, 'msg' => 'La caja no está disponible.']);
            return;
        }

        // Validar saldo para egresos
        if ($tipo === 'E' && $monto > (float)$caja->monto_actual) {
            echo json_encode(['status' => false, 'msg' => 'Saldo insuficiente. Saldo actual: S/ ' . number_format($caja->monto_actual, 2)]);
            return;
        }

        $movData = [
            'caja_id'    => $caja_id,
            'moneda_id'  => $caja->moneda_id,
            'tipo'       => $tipo,
            'origen'     => $origen,
            'fecha'      => $fecha,
            'monto'      => $monto,
            'concepto'   => $concepto,
            'created_by' => $this->session->userdata('id'),
            'created_at' => date('Y-m-d H:i:s'),
        ];

        // Campos opcionales según origen
        if ($origen === 'BANCO') {
            $movData['banco_cuenta_id']    = (int)$this->input->post('banco_cuenta_id', TRUE) ?: NULL;
            $movData['banco_nro_operacion']= $this->input->post('banco_nro_operacion', TRUE) ?: NULL;
        }

        if ($tipo === 'E') {
            $movData['proveedor_nombre']   = $this->input->post('proveedor_nombre', TRUE) ?: NULL;
            $movData['proveedor_ruc']      = $this->input->post('proveedor_ruc', TRUE) ?: NULL;
            $movData['tiene_comprobante']  = (int)$this->input->post('tiene_comprobante', TRUE);
            $movData['tipo_comprobante']   = $this->input->post('tipo_comprobante', TRUE) ?: NULL;
            $movData['nro_comprobante']    = $this->input->post('nro_comprobante', TRUE) ?: NULL;
        }

        $this->db->trans_start();

        $this->CajaChica_model->insertar_movimiento($movData);

        // Actualizar saldo
        $nuevoSaldo = $tipo === 'I'
            ? (float)$caja->monto_actual + $monto
            : (float)$caja->monto_actual - $monto;

        $this->CajaChica_model->actualizar_saldo($caja_id, $nuevoSaldo);

        $this->db->trans_complete();

        if ($this->db->trans_status() === FALSE) {
            echo json_encode(['status' => false, 'msg' => 'Error al registrar el movimiento.']);
            return;
        }

        echo json_encode([
            'status'      => true,
            'msg'         => 'Movimiento registrado correctamente.',
            'nuevo_saldo' => number_format($nuevoSaldo, 2),
        ]);
    }

    // -------------------------------------------------------
    // CIERRE
    // -------------------------------------------------------
    public function cierre($id) {
        $this->validar_permiso('caja_chica_cierre');

        $caja = $this->CajaChica_model->obtener_completo($id);
        if (!$caja || $caja->estado_codigo !== 'ABT') {
            $this->session->set_flashdata('error', 'La caja no está disponible para cierre.');
            redirect('finanzas/caja_chica');
        }

        $estadoCerrada = $this->CajaChica_model->obtener_estado('CAJA_CHICA', 'CRR');

        $this->CajaChica_model->actualizar_caja($id, [
            'estado_id'   => $estadoCerrada->id,
            'fecha_cierre'=> date('Y-m-d'),
            'updated_by'  => $this->session->userdata('id'),
            'updated_at'  => date('Y-m-d H:i:s'),
        ]);

        $this->session->set_flashdata('success', 'Caja cerrada correctamente. Saldo disponible para próxima apertura: S/ ' . number_format($caja->monto_actual, 2));
        redirect('finanzas/caja_chica/ver/' . $id);
    }

    // -------------------------------------------------------
    // REPORTE — print de rendición
    // -------------------------------------------------------
    public function reporte($id) {
        $this->validar_permiso('caja_chica_reporte');

        $caja = $this->CajaChica_model->obtener_completo($id);
        if (!$caja) show_404();

        $data['caja']        = $caja;
        $data['movimientos'] = $this->CajaChica_model->listar_movimientos($id);
        $data['resumen']     = $this->CajaChica_model->obtener_resumen($id);
        $data['empresa']     = $this->Empresa_model->obtener_activa();

        $this->load->view('finanzas/caja_chica/reporte', $data);
    }
}