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

class FacturaServicio extends MY_Controller {

    public function __construct() {
        parent::__construct();
        $this->load->model('logistica/FacturaServicio_model');
    }

    protected function validar_permiso_ajax($slug) {
        if (!tiene_permiso($slug)) {
            echo json_encode(array('status' => false, 'message' => 'No tienes permisos'));
            exit;
        }
    }

    // ---------------------------------------------------------------
    // LISTADO
    // ---------------------------------------------------------------
    public function index() {
        $this->validar_permiso('factura_servicio_ver');

        $data['titulo']    = 'Facturas de Servicios';
        $data['facturas']  = $this->FacturaServicio_model->listar();
        $this->layout('logistica/factura_servicio/index', $data);
    }

    // ---------------------------------------------------------------
    // NUEVO
    // ---------------------------------------------------------------
    public function create() {
        $this->validar_permiso('factura_servicio_crear');

        $data['titulo']          = 'Nueva Factura de Servicio';
        $data['monedas']         = $this->FacturaServicio_model->listar_monedas();
        $data['formas_pago']     = $this->FacturaServicio_model->listar_formas_pago();
        $data['sectores']        = $this->FacturaServicio_model->listar_sectores_negocio();
        $this->layout('logistica/factura_servicio/create', $data);
    }

    // ---------------------------------------------------------------
    // GUARDAR
    // ---------------------------------------------------------------
    public function store() {
        $this->validar_permiso('factura_servicio_crear');

        $this->form_validation->set_rules('proveedor_id',     'Proveedor',        'required');
        $this->form_validation->set_rules('tipo_comprobante', 'Tipo comprobante', 'required');

        $tipo = $this->input->post('tipo_comprobante', TRUE);
        if ($tipo !== 'O') {
            $this->form_validation->set_rules('serie',  'Serie',  'required|trim|max_length[10]');
            $this->form_validation->set_rules('numero', 'Número', 'required|trim|max_length[20]');
        } else {
            $this->form_validation->set_rules('serie',  'Serie',  'trim|max_length[10]');
            $this->form_validation->set_rules('numero', 'Número', 'trim|max_length[20]');
        }

        $this->form_validation->set_rules('fecha_emision',    'Fecha emisión',    'required');
        $this->form_validation->set_rules('moneda_id',        'Moneda',           'required');
        $this->form_validation->set_rules('total',            'Total',            'required');

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

        $proveedor_id      = $this->input->post('proveedor_id', TRUE);
        $tipo_comprobante  = $this->input->post('tipo_comprobante', TRUE);
        $serie             = strtoupper(trim($this->input->post('serie', TRUE)));
        $numero            = trim($this->input->post('numero', TRUE));
        $fecha_emision     = $this->input->post('fecha_emision', TRUE);
        $fecha_vencimiento = $this->input->post('fecha_vencimiento', TRUE) ?: null;
        $moneda_id         = $this->input->post('moneda_id', TRUE);
        $tipocambio        = $this->input->post('tipocambio', TRUE) ?: null;
        $subtotal          = (float)$this->input->post('subtotal', TRUE);
        $igv_porcentaje    = (float)$this->input->post('igv_porcentaje', TRUE);
        $igv               = (float)$this->input->post('igv', TRUE);
        $total             = (float)$this->input->post('total', TRUE);
        $fp_id             = $this->input->post('fp_id', TRUE) ?: null;
        $observaciones     = trim($this->input->post('observaciones', TRUE));
        $detalle           = $this->input->post('detalle');
        $cuotas            = $this->input->post('cuotas');

        // Verificar duplicado
        if ($this->FacturaServicio_model->existe_comprobante($proveedor_id, $tipo_comprobante, $serie, $numero)) {
            $this->session->set_flashdata('error', 'Ya existe un comprobante con esa serie y número para este proveedor.');
            redirect('logistica/factura_servicio/create');
        }

        // Validar que tenga al menos un ítem en el detalle
        $detalleValido = [];
        if (!empty($detalle) && is_array($detalle)) {
            foreach ($detalle as $item) {
                if (empty($item['sector_negocio_id']) || empty($item['descripcion'])) continue;
                $detalleValido[] = $item;
            }
        }

        if (empty($detalleValido)) {
            $this->session->set_flashdata('error', 'Debe agregar al menos un servicio en el detalle.');
            redirect('logistica/factura_servicio/create');
        }

        $cabecera = array(
            'proveedor_id'      => $proveedor_id,
            'tipo_gasto'        => 'S',
            'tipo_comprobante'  => $tipo_comprobante,
            'serie'             => $serie,
            'numero'            => $numero,
            'fecha_emision'     => $fecha_emision,
            'fecha_vencimiento' => $fecha_vencimiento,
            'moneda_id'         => $moneda_id,
            'tipocambio'        => $tipocambio,
            'subtotal'          => $subtotal,
            'igv_porcentaje'    => $igv_porcentaje,
            'igv'               => $igv,
            'total'             => $total,
            'saldo'             => $total,
            'fp_id'             => $fp_id,
            'observaciones'     => $observaciones !== '' ? $observaciones : null,
            'estado'            => 1, // PENDIENTE
            'created_by'        => $this->session->userdata('id')
        );

        $this->db->trans_begin();

        $cp_id = $this->FacturaServicio_model->insertar($cabecera);

        if (!$cp_id) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'No se pudo registrar la factura.');
            redirect('logistica/factura_servicio/create');
        }

        // Insertar detalle de servicios
        $detalleInsert = [];
        foreach ($detalleValido as $item) {
            $cant    = (float)$item['cantidad'];
            $precio  = (float)$item['precio_unitario'];
            $detalleInsert[] = array(
                'cp_id'             => $cp_id,
                'sector_negocio_id' => (int)$item['sector_negocio_id'],
                'descripcion'       => trim($item['descripcion']),
                'cantidad'          => $cant,
                'unidad'            => !empty($item['unidad']) ? trim($item['unidad']) : null,
                'precio_unitario'   => $precio,
                'subtotal'          => round($cant * $precio, 2),
                'created_by'        => $this->session->userdata('id'),
            );
        }
        $this->FacturaServicio_model->insertar_detalle_batch($detalleInsert);

        // Insertar cuotas si las hay
        if (!empty($cuotas) && is_array($cuotas)) {
            $cuotasInsert = [];
            foreach ($cuotas as $cuota) {
                $imp = (float)$cuota['importe'];
                if ($imp <= 0) continue;
                $cuotasInsert[] = array(
                    'cp_id'             => $cp_id,
                    'nro_cuota'         => (int)$cuota['nro_cuota'],
                    'fecha_vencimiento' => $cuota['fecha_vencimiento'],
                    'importe'           => $imp,
                    'saldo'             => $imp,
                    'estado'            => 0,
                );
            }
            if (!empty($cuotasInsert)) {
                $this->FacturaServicio_model->insertar_cuotas_batch($cuotasInsert);
            }
        }

        if ($this->db->trans_status() === FALSE) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'Error al guardar la factura.');
            redirect('logistica/factura_servicio/create');
        }

        $this->db->trans_commit();

        $this->session->set_flashdata('success', 'Factura ' . $serie . '-' . $numero . ' registrada correctamente.');
        redirect('logistica/factura_servicio');
    }

    // ---------------------------------------------------------------
    // VER
    // ---------------------------------------------------------------
    public function ver($id) {
        $this->validar_permiso('factura_servicio_ver');

        $factura = $this->FacturaServicio_model->obtener_completo($id);
        if (!$factura || $factura->tipo_gasto !== 'S') show_404();

        $data['titulo']   = 'Detalle Factura de Servicio';
        $data['factura']  = $factura;
        $data['detalle']  = $this->FacturaServicio_model->obtener_detalle($id);
        $data['cuotas']   = $this->FacturaServicio_model->obtener_cuotas($id);
        $data['pagos']    = $this->FacturaServicio_model->obtener_pagos($id);
        $data['medios_pago'] = $this->FacturaServicio_model->listar_medios_pago();
        $data['cuentas']  = $this->FacturaServicio_model->listar_cuentas_bancarias();
        $this->layout('logistica/factura_servicio/ver', $data);
    }

    // ---------------------------------------------------------------
    // REGISTRAR PAGO (AJAX) — misma lógica que ComprobanteProveedor
    // ---------------------------------------------------------------
    public function registrar_pago() {
        $this->validar_permiso_ajax('factura_servicio_pagar');

        $cp_id           = $this->input->post('cp_id', TRUE);
        $cuota_id        = $this->input->post('cuota_id', TRUE) ?: null;
        $fecha_pago      = $this->input->post('fecha_pago', TRUE);
        $medio_pago_id   = $this->input->post('medio_pago_id', TRUE);
        $banco_cuenta_id = $this->input->post('banco_cuenta_id', TRUE) ?: null;
        $importe         = (float)$this->input->post('importe', TRUE);
        $referencia      = trim($this->input->post('referencia', TRUE));
        $observaciones   = trim($this->input->post('observaciones', TRUE));

        if ($importe <= 0) {
            echo json_encode(array('status' => false, 'message' => 'El importe debe ser mayor a 0'));
            return;
        }

        $factura = $this->FacturaServicio_model->obtener($cp_id);
        if (!$factura) {
            echo json_encode(array('status' => false, 'message' => 'Factura no encontrada'));
            return;
        }

        if ($importe > (float)$factura->saldo) {
            echo json_encode(array('status' => false, 'message' => 'El importe supera el saldo pendiente (' . number_format($factura->saldo, 2) . ')'));
            return;
        }

        $this->db->trans_begin();

        $this->FacturaServicio_model->registrar_pago(array(
            'cp_id'           => $cp_id,
            'cuota_id'        => $cuota_id,
            'fecha_pago'      => $fecha_pago,
            'medio_pago_id'   => $medio_pago_id,
            'banco_cuenta_id' => $banco_cuenta_id,
            'importe'         => $importe,
            'referencia'      => $referencia !== '' ? $referencia : null,
            'observaciones'   => $observaciones !== '' ? $observaciones : null,
            'created_by'      => $this->session->userdata('id'),
        ));

        $nuevo_saldo  = round((float)$factura->saldo - $importe, 2);
        $nuevo_estado = $nuevo_saldo <= 0 ? 2 : 1;

        $this->FacturaServicio_model->actualizar($cp_id, array(
            'saldo'      => $nuevo_saldo,
            'estado'     => $nuevo_estado,
            'updated_at' => date('Y-m-d H:i:s'),
            'updated_by' => $this->session->userdata('id'),
        ));

        if ($cuota_id) {
            $cuota = $this->db->where('id', $cuota_id)->get('cp_comprobante_proveedor_cuota')->row();
            if ($cuota) {
                $saldo_cuota  = max(0, round((float)$cuota->saldo - $importe, 2));
                $estado_cuota = $saldo_cuota <= 0 ? 1 : 0;
                $this->FacturaServicio_model->actualizar_cuota($cuota_id, array(
                    'saldo'  => $saldo_cuota,
                    'estado' => $estado_cuota,
                ));
            }
        }

        if ($this->db->trans_status() === FALSE) {
            $this->db->trans_rollback();
            echo json_encode(array('status' => false, 'message' => 'Error al registrar el pago'));
            return;
        }

        $this->db->trans_commit();

        echo json_encode(array(
            'status'      => true,
            'message'     => 'Pago registrado correctamente',
            'nuevo_saldo' => number_format($nuevo_saldo, 2),
            'pagado'      => $nuevo_estado == 2,
        ));
    }

    // ---------------------------------------------------------------
    // ANULAR
    // ---------------------------------------------------------------
    public function anular($id) {
        $this->validar_permiso('factura_servicio_anular');

        $factura = $this->FacturaServicio_model->obtener($id);
        if (!$factura) show_404();

        if ($factura->estado == 3) {
            $this->session->set_flashdata('error', 'La factura ya está anulada.');
            redirect('logistica/factura_servicio');
        }

        if ($factura->saldo < $factura->total) {
            $this->session->set_flashdata('error', 'No se puede anular una factura con pagos registrados.');
            redirect('logistica/factura_servicio');
        }

        $this->FacturaServicio_model->actualizar($id, array(
            'estado'     => 3,
            'updated_at' => date('Y-m-d H:i:s'),
            'updated_by' => $this->session->userdata('id'),
        ));

        $this->session->set_flashdata('success', 'Factura anulada correctamente.');
        redirect('logistica/factura_servicio');
    }

    // ---------------------------------------------------------------
    // AJAX — BUSCAR PROVEEDOR
    // ---------------------------------------------------------------
    public function buscar_proveedor() {
        $this->validar_permiso_ajax('factura_servicio_crear');
        $term = trim($this->input->get('term', TRUE));
        if (strlen($term) < 2) { echo json_encode(array()); return; }

        $proveedores = $this->FacturaServicio_model->buscar_proveedor($term);
        $resultado   = array();
        foreach ($proveedores as $item) {
            $resultado[] = array(
                'id'            => $item->id,
                'label'         => $item->razon_social . ' | ' . $item->nro_documento,
                'value'         => $item->razon_social,
                'razon_social'  => $item->razon_social,
                'nro_documento' => $item->nro_documento,
                'fp_id'         => $item->fp_id,
                'moneda_id'     => $item->moneda_id,
                'sector'        => $item->sector_negocio,
            );
        }
        echo json_encode($resultado);
    }
}
