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

class Guiaremitente extends MY_Controller {

    public function __construct() {
        parent::__construct();
        $this->load->model('almacen/Guiaremitente_model');
        $this->load->model('configuracion/Empresa_model');
        $this->load->model('ventas/Orden_pedido_model');
    }

    private function cargarCombos() {
        return array(
            'motivos'           => $this->Guiaremitente_model->listar_motivos(),
            'clientes'          => $this->Guiaremitente_model->listar_clientes(),
            'unidades_peso'     => $this->Guiaremitente_model->listar_unidades_peso(),
            'origenes'          => $this->Guiaremitente_model->listar_origenes(),
            'destinos'          => $this->Guiaremitente_model->listar_destinos(),
            'vehiculos'         => $this->Guiaremitente_model->listar_vehiculos(),
            'conductores'       => $this->Guiaremitente_model->listar_conductores(),
            'transportistas'    => $this->Guiaremitente_model->listar_transportistas()
        );
    }

    private function validarTransporte($tipo_transporte, $vehiculo_id, $conductor_id, $transportista_id) {
        if ($tipo_transporte == 'PRIVADO') {
            if (empty($vehiculo_id)) {
                return 'Debe seleccionar un vehículo para transporte privado';
            }
            if (empty($conductor_id)) {
                return 'Debe seleccionar un conductor para transporte privado';
            }
        }

        if ($tipo_transporte == 'PUBLICO') {
            if (empty($transportista_id)) {
                return 'Debe seleccionar un transportista para transporte público';
            }
        }

        return true;
    }

    public function index() {
        $this->validar_permiso('grremitente_ver');

        $data['titulo'] = 'Guía de Remisión Remitente';
        $data['guias'] = $this->Guiaremitente_model->listar();

        $this->layout('almacen/guiaremitente/index', $data);
    }

    public function create() {
        $this->validar_permiso('grremitente_crear');

        $tipoComprobante = $this->Guiaremitente_model->obtener_tipo_comprobante_guia();

        $data['titulo'] = 'Nueva Guía Remitente';
        $data['serie_actual'] = $tipoComprobante ? $tipoComprobante->serie : '';
        $data['numero_actual'] = $tipoComprobante ? str_pad($tipoComprobante->correlativo_actual, 8, '0', STR_PAD_LEFT) : '';

        $data = array_merge($data, $this->cargarCombos());

        $this->layout('almacen/guiaremitente/create', $data);
    }

    public function store() {
        $this->validar_permiso('grremitente_crear');
        $this->form_validation->set_rules('fecha_emision', 'Fecha de Emision', 'required');
        $this->form_validation->set_rules('motivo_traslado_id', 'Motivo de traslado', 'required');
        $this->form_validation->set_rules('cliente_id', 'Cliente', 'required');
        $this->form_validation->set_rules('um_peso_bruto_id', 'Unidad de peso bruto', 'required');
        $this->form_validation->set_rules('peso_bruto_carga', 'Peso bruto carga', 'required|numeric');
        $this->form_validation->set_rules('origen_id', 'Origen', 'required');
        $this->form_validation->set_rules('destino_id', 'Destino', 'required');
        $this->form_validation->set_rules('tipo_transporte', 'Tipo transporte', 'required');
        $this->form_validation->set_rules('fecha_traslado', 'Fecha traslado', 'required');


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

        $tipo_transporte    = $this->input->post('tipo_transporte', TRUE);
        $vehiculo_id        = $this->input->post('vehiculo_id', TRUE);
        $conductor_id       = $this->input->post('conductor_id', TRUE);
        $transportista_id   = $this->input->post('transportista_id', TRUE);
        $fecha_traslado     = date('Y-m-d H:i:s', strtotime($this->input->post('fecha_traslado', TRUE)));

        $detalle_producto_id    = $this->input->post('detalle_producto_id');
        $detalle_um_id_venta    = $this->input->post('detalle_um_id_venta');
        $detalle_cantidad       = $this->input->post('detalle_cantidad');
        $detalle_comprob_id     = $this->input->post('detalle_comprob_id');

        $validacion = $this->validarTransporte($tipo_transporte, $vehiculo_id, $conductor_id, $transportista_id);

        if ($validacion !== true) {
            $this->session->set_flashdata('error', $validacion);
            redirect('almacen/guiaremitente/create');
        }

        if (empty($detalle_producto_id) || !is_array($detalle_producto_id)) {
            $this->session->set_flashdata('error', 'Debe agregar al menos un producto al detalle');
            redirect('almacen/guiaremitente/create');
        }

        $tipoComprobante = $this->Guiaremitente_model->obtener_tipo_comprobante_guia();

        if (!$tipoComprobante) {
            $this->session->set_flashdata('error', 'No se encontró configuración del tipo de comprobante para guía de remisión remitente');
            redirect('almacen/guiaremitente/create');
        }

        $serie              = trim($tipoComprobante->serie);
        $correlativoActual  = (int)$tipoComprobante->correlativo_actual;
        $numero             = str_pad($correlativoActual, 8, '0', STR_PAD_LEFT);

        $data = array(
            'serie'                 => $serie,
            'numero'                => $numero,
            'fecha_emision'         => $this->input->post('fecha_emision', TRUE),
            'comercio_exterior'     => $this->input->post('comercio_exterior') ? 1 : 0,
            'motivo_traslado_id'    => $this->input->post('motivo_traslado_id', TRUE),
            'cliente_id'            => $this->input->post('cliente_id', TRUE),
            'um_peso_bruto_id'      => $this->input->post('um_peso_bruto_id', TRUE),
            'peso_bruto_carga'      => $this->input->post('peso_bruto_carga', TRUE),
            'origen_id'             => $this->input->post('origen_id', TRUE),
            'destino_id'            => $this->input->post('destino_id', TRUE),
            'tipo_transporte'       => $tipo_transporte,
            'transbordo_programado' => $this->input->post('transbordo_programado') ? 1 : 0,
            'traslado_vehiculo'     => $this->input->post('traslado_vehiculo') ? 1 : 0,
            'vehiculo_id'           => ($tipo_transporte == 'PRIVADO') ? $vehiculo_id : null,
            'conductor_id'          => ($tipo_transporte == 'PRIVADO') ? $conductor_id : null,
            'transportista_id'      => ($tipo_transporte == 'PUBLICO') ? $transportista_id : null,
            'fecha_traslado'        => $fecha_traslado,
            'retorno_envases_vacios' => $this->input->post('retorno_envases_vacios') ? 1 : 0,
            'retorno_vehiculo_vacio' => ($tipo_transporte == 'PRIVADO' && $this->input->post('retorno_vehiculo_vacio')) ? 1 : 0,
            'observaciones'         => trim($this->input->post('observaciones', TRUE)),
            'estado_id'             => 29,
            'created_by'            => $this->session->userdata('id')
        );

        $this->db->trans_begin();

        $grId = $this->Guiaremitente_model->insertar($data);

        if (!$grId) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'No se pudo registrar la guía');
            redirect('almacen/guiaremitente/create');
        }

        $this->Guiaremitente_model->insertar_estado(array(
            'gr_remitente_id'           => $grId,
            'estado_id'                 => 29,
            'gr_remitente_fechaestado'  => date('Y-m-d H:i:s'),
            'usuario_id'                => $this->session->userdata('id')
        ));

        for ($i = 0; $i < count($detalle_producto_id); $i++) {
            if (empty($detalle_producto_id[$i]) || empty($detalle_um_id_venta[$i]) || empty($detalle_cantidad[$i])) {
                continue;
            }

            $detalle = array(
                'gr_remitente_id'   => $grId,
                'producto_id'       => $detalle_producto_id[$i],
                'um_id'             => $detalle_um_id_venta[$i],
                'cantidad'          => $detalle_cantidad[$i]
            );

            $this->Guiaremitente_model->insertar_detalle($detalle);
        }

        if (!empty($detalle_comprob_id) && is_array($detalle_comprob_id)) {
            foreach ($detalle_comprob_id as $comprobId) {
                if (empty($comprobId)) {
                    continue;
                }

                $this->Guiaremitente_model->insertar_comprobante_relacionado(array(
                    'gr_remitente_id'       => $grId,
                    'nrofactbolt_id'        => $comprobId
                ));
            }
        }

        $nuevoCorrelativo = $correlativoActual + 1;
        $this->Guiaremitente_model->actualizar_correlativo_tipo_comprobante($tipoComprobante->id, $nuevoCorrelativo);

        if ($this->db->trans_status() === FALSE) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'No se pudo registrar la guía de remisión');
            redirect('almacen/guiaremitente/create');
        }

        $this->db->trans_commit();

        $this->session->set_flashdata('success', 'Guía registrada correctamente: ' . $serie . '-' . $numero);
        redirect('almacen/guiaremitente');
    }

    public function edit($id) {
        $this->validar_permiso('grremitente_editar');

        $guia = $this->Guiaremitente_model->obtener($id);


        if (!$guia) {
            show_404();
        }

        $data['titulo']         = 'Editar Guía Remitente';
        $data['guia']           = $guia;
        $data['detalle']        = $this->Guiaremitente_model->obtener_detalle_guia($id);
        $data['comprobantes']   = $this->Guiaremitente_model->obtener_comprobantes_relacionados($id);
        $data                   = array_merge($data, $this->cargarCombos());

        $this->layout('almacen/guiaremitente/edit', $data);
    }

    public function update($id) {
        $this->validar_permiso('grremitente_editar');

        $guia = $this->Guiaremitente_model->obtener($id);

        if (!$guia) {
            show_404();
        }

        // VALIDACIONES
        $this->form_validation->set_rules('motivo_traslado_id', 'Motivo de traslado', 'required');
        $this->form_validation->set_rules('cliente_id', 'Cliente', 'required');
        $this->form_validation->set_rules('um_peso_bruto_id', 'Unidad de peso bruto', 'required');
        $this->form_validation->set_rules('peso_bruto_carga', 'Peso bruto carga', 'required|numeric');
        $this->form_validation->set_rules('origen_id', 'Origen', 'required');
        $this->form_validation->set_rules('destino_id', 'Destino', 'required');
        $this->form_validation->set_rules('tipo_transporte', 'Tipo transporte', 'required');
        $this->form_validation->set_rules('fecha_traslado', 'Fecha traslado', 'required');

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

        $tipo_transporte = $this->input->post('tipo_transporte', TRUE);
        $vehiculo_id = $this->input->post('vehiculo_id', TRUE);
        $conductor_id = $this->input->post('conductor_id', TRUE);
        $transportista_id = $this->input->post('transportista_id', TRUE);

        $validacion = $this->validarTransporte($tipo_transporte, $vehiculo_id, $conductor_id, $transportista_id);

        if ($validacion !== true) {
            $this->session->set_flashdata('error', $validacion);
            redirect('almacen/guiaremitente/edit/' . $id);
        }

        // DETALLE
        $detalle_producto_id = $this->input->post('detalle_producto_id');
        $detalle_um_id_venta = $this->input->post('detalle_um_id_venta');
        $detalle_cantidad = $this->input->post('detalle_cantidad');
        $detalle_comprob_id = $this->input->post('detalle_comprob_id');

        if (empty($detalle_producto_id)) {
            $this->session->set_flashdata('error', 'Debe agregar al menos un producto');
            redirect('almacen/guiaremitente/edit/' . $id);
        }

        $data = array(
            'fecha_emision'          => $this->input->post('fecha_emision', TRUE),
            'comercio_exterior'      => $this->input->post('comercio_exterior') ? 1 : 0,
            'motivo_traslado_id'     => $this->input->post('motivo_traslado_id', TRUE),
            'cliente_id'             => $this->input->post('cliente_id', TRUE),
            'um_peso_bruto_id'       => $this->input->post('um_peso_bruto_id', TRUE),
            'peso_bruto_carga'       => $this->input->post('peso_bruto_carga', TRUE),
            'origen_id'              => $this->input->post('origen_id', TRUE),
            'destino_id'             => $this->input->post('destino_id', TRUE),
            'tipo_transporte'        => $tipo_transporte,
            'transbordo_programado'  => $this->input->post('transbordo_programado') ? 1 : 0,
            'traslado_vehiculo'      => $this->input->post('traslado_vehiculo') ? 1 : 0,
            'vehiculo_id'            => ($tipo_transporte == 'PRIVADO') ? $vehiculo_id : null,
            'conductor_id'           => ($tipo_transporte == 'PRIVADO') ? $conductor_id : null,
            'transportista_id'       => ($tipo_transporte == 'PUBLICO') ? $transportista_id : null,
            'fecha_traslado'         => date('Y-m-d H:i:s', strtotime($this->input->post('fecha_traslado'))),
            'retorno_envases_vacios' => $this->input->post('retorno_envases_vacios') ? 1 : 0,
            'retorno_vehiculo_vacio' => $this->input->post('retorno_vehiculo_vacio') ? 1 : 0,
            'observaciones'          => trim($this->input->post('observaciones')),
            'updated_at'             => date('Y-m-d H:i:s'),
            'updated_by'             => $this->session->userdata('id')
        );

        $this->db->trans_begin();

        // ACTUALIZAR CABECERA
        $this->Guiaremitente_model->actualizar($id, $data);

        // 🔥 ELIMINAR DETALLE ANTERIOR
        $this->db->where('gr_remitente_id', $id)->delete('al_gr_remitente_detalle');

        // INSERTAR NUEVO DETALLE
        for ($i = 0; $i < count($detalle_producto_id); $i++) {

            if (empty($detalle_producto_id[$i])) continue;

            $this->Guiaremitente_model->insertar_detalle(array(
                'gr_remitente_id'   => $id,
                'producto_id'       => $detalle_producto_id[$i],
                'um_id'             => $detalle_um_id_venta[$i],
                'cantidad'          => $detalle_cantidad[$i]
            ));
        }

        // 🔥 ELIMINAR COMPROBANTES
        $this->db->where('gr_remitente_id', $id)->delete('al_gr_remitente_comprob');

        // INSERTAR NUEVOS
        if (!empty($detalle_comprob_id)) {
            foreach ($detalle_comprob_id as $comprobId) {
                if (empty($comprobId)) continue;

                $this->Guiaremitente_model->insertar_comprobante_relacionado(array(
                    'gr_remitente_id' => $id,
                    'nrofactbolt_id' => $comprobId
                ));
            }
        }

        if ($this->db->trans_status() === FALSE) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'Error al actualizar');
        } else {
            $this->db->trans_commit();
            $this->session->set_flashdata('success', 'Guía actualizada correctamente');
        }

        redirect('almacen/guiaremitente');
    }

    public function buscar_clientes() {
        $term = trim($this->input->get('term', TRUE));

        if (strlen($term) < 2) {
            echo json_encode(array());
            return;
        }

        $clientes = $this->Guiaremitente_model->buscar_clientes($term);
        $resultado = array();

        foreach ($clientes as $item) {
            $resultado[] = array(
                'id' => $item->id,
                'label' => $item->nro_documento . ' - ' . $item->razon_social,
                'value' => $item->nro_documento . ' - ' . $item->razon_social,
                'razon_social' => $item->razon_social,
                'nro_documento' => $item->nro_documento
            );
        }

        echo json_encode($resultado);
    }

    public function buscar_productos() {
        $term = trim($this->input->get('term', TRUE));

        if (strlen($term) < 2) {
            echo json_encode(array());
            return;
        }

        $productos = $this->Guiaremitente_model->buscar_productos($term);
        $resultado = array();

        foreach ($productos as $item) {
            $resultado[] = array(
                'id'            => $item->id,
                'label'         => $item->codigo . ' - ' . $item->nombre,
                'value'         => $item->codigo . ' - ' . $item->nombre,
                'nombre'        => $item->nombre,
                'um_id_venta'   => $item->um_id_venta
            );
        }

        echo json_encode($resultado);
    }

    public function buscar_comprobantes() {
        $term = trim($this->input->get('term', TRUE));

        if (strlen($term) < 2) {
            echo json_encode(array());
            return;
        }

        $comprobantes = $this->Guiaremitente_model->buscar_comprobantes($term);
        $resultado = array();

        foreach ($comprobantes as $item) {
            $resultado[] = array(
                'id' => $item->id,
                'label' => $item->serie . '-' . $item->numero . ' | ' . $item->razon_social,
                'value' => $item->serie . '-' . $item->numero . ' | ' . $item->razon_social,
                'serie' => $item->serie,
                'numero' => $item->numero,
                'cliente_id' => $item->cliente_id,
                'razon_social' => $item->razon_social
            );
        }

        echo json_encode($resultado);
    }

    public function obtener_detalle_comprobante() {
        $comprob_id = $this->input->get('comprob_id', TRUE);

        if (empty($comprob_id)) {
            echo json_encode(array());
            return;
        }

        $detalle = $this->Guiaremitente_model->obtener_detalle_comprobante($comprob_id);

        echo json_encode($detalle);
    }

    public function ver($id) {
        $this->validar_permiso('grremitente_ver');

        $guia = $this->Guiaremitente_model->obtener_completo($id);

        if (!$guia) {
            show_404();
        }

        $detalle = $this->Guiaremitente_model->obtener_detalle_guia($id);
        $comprobantes = $this->Guiaremitente_model->obtener_comprobantes_relacionados($id);
        $historial = $this->Guiaremitente_model->listar_historial_estados($id);

        $data['titulo'] = 'Ver Guía Remitente';
        $data['guia'] = $guia;
        $data['detalle'] = $detalle;
        $data['comprobantes'] = $comprobantes;
        $data['historial'] = $historial;

        $this->layout('almacen/guiaremitente/ver', $data);
    }    


    public function print($id) {
        $this->validar_permiso('grremitente_ver');

        $guia = $this->db
            ->select("
                g.*,

                m.nombre as motivo_nombre,

                cli.razon_social as cliente_nombre,
                cli.nro_documento as cliente_nro_documento,

                tdoc.nombre as cliente_doc_nombre,
                tdoc.abreviado as cliente_doc_abreviado,

                ori.sucursales as origen_descripcion,
                des.direccion as destino_descripcion,

                ump.nombre as um_peso_bruto_nombre,
                ump.abreviado as um_peso_bruto_abreviado,

                veh.nro_placa as vehiculo_placa,
                veh.marca as vehiculo_marca,
                veh.nro_autorizacion as vehiculo_nro_autorizacion,

                ee.nombre as vehiculo_entidad_emisora,
                ee.codigo as abreviado_entidad_emisora,

                cond.nombre as conductor_nombre,
                cond.nro_licencia as conductor_licencia,
                cond.nro_documento as conductor_nro_documento,

                cdoc.nombre as conductor_doc_nombre,
                cdoc.abreviado as conductor_doc_abreviado,

                tr.ruc as transportista_ruc,
                tr.razon_social as transportista_nombre,
                tr.nro_registro_mtc as transportista_registro_mtc,
                tr.nro_autorizacion as transportista_nro_autorizacion,

                est.nombre as estado_nombre
            ")
            ->from('al_gr_remitente g')
            ->join('mt_motivo_traslado m', 'm.id = g.motivo_traslado_id', 'left')
            ->join('vt_cliente cli', 'cli.id = g.cliente_id', 'left')
            ->join('mt_documento_identidad tdoc', 'tdoc.id = cli.documento_identidad_id', 'left')
            ->join('empresa_detalle ori', 'ori.id = g.origen_id', 'left')
            ->join('vt_cliente_local des', 'des.id = g.destino_id', 'left')
            ->join('mt_unidad_medida ump', 'ump.id = g.um_peso_bruto_id', 'left')
            ->join('mt_vehiculo veh', 'veh.id = g.vehiculo_id', 'left')
            ->join('mt_entidad_emisora ee', 'ee.id = veh.entidad_emisora_id', 'left')
            ->join('mt_conductor cond', 'cond.id = g.conductor_id', 'left')
            ->join('mt_documento_identidad cdoc', 'cdoc.id = cond.documento_identidad_id', 'left')
            ->join('mt_transportista tr', 'tr.id = g.transportista_id', 'left')
            ->join('estado est', 'est.id = g.estado_id', 'left')
            ->where('g.id', $id)
            ->get()
            ->row();

            if (!$guia) {
                show_404();
            }

            $detalle = $this->db
                ->select("
                    d.*,
                    p.codigo,
                    p.nombre,
                    p.descripcion as producto_descripcion,
                    um.nombre as unidad_medida_nombre,
                    um.abreviado as unidad_medida_abreviado
                ")
                ->from('al_gr_remitente_detalle d')
                ->join('vt_producto p', 'p.id = d.producto_id', 'left')
                ->join('mt_unidad_medida um', 'um.id = d.um_id', 'left')
                ->where('d.gr_remitente_id', $id)
                ->order_by('d.id', 'ASC')
                ->get()
                ->result();

            $comprobantes = $this->db
                ->select("
                    rc.*,
                    c.serie,
                    c.numero,
                    tc.nombre as tipo_comprobante_nombre,
                    tc.nombre_corto as tipo_comprobante_corto,
                    cli.razon_social as cliente_nombre,
                    cli.nro_documento as cliente_nro_documento
                ")
                ->from('al_gr_remitente_comprob rc')
                ->join('vt_comprobante c', 'c.id = rc.nrofactbolt_id', 'left')
                ->join('mt_tipo_comprobante tc', 'tc.id = c.comprobante_id', 'left')
                ->join('vt_cliente cli', 'cli.id = c.cliente_id', 'left')
                ->where('rc.gr_remitente_id', $id)
                ->order_by('rc.id', 'ASC')
                ->get()
                ->result();

            $empresa = $this->Empresa_model->obtener_activa();

            // ===== TEXTO QR =====
            // Ajusta esta estructura si luego quieres otro formato exacto.
            $qrTexto = implode('|', array(
                !empty($empresa->ruc) ? $empresa->ruc : '',
                '09', // codigo documento SUNAT para guía remitente
            $guia->serie,
            $guia->numero,
            !empty($guia->fecha_traslado) ? date('d/m/Y', strtotime($guia->fecha_traslado)) : '',
            !empty($guia->cliente_nro_documento) ? $guia->cliente_nro_documento : '',
            !empty($guia->cliente_nombre) ? $guia->cliente_nombre : '',
            !empty($guia->peso_bruto_carga) ? $guia->peso_bruto_carga : '0'
        ));

        // ===== GENERACION QR =====
        $this->load->helper('file');
        require_once(APPPATH . 'libraries/phpqrcode/qrlib.php');

        $qrDir = FCPATH . 'uploads/qr/';
        if (!is_dir($qrDir)) {
            mkdir($qrDir, 0777, true);
        }

        $qrFileName = 'gr_' . $guia->id . '.png';
        $qrFilePath = $qrDir . $qrFileName;

        QRcode::png($qrTexto, $qrFilePath, QR_ECLEVEL_L, 4, 1);

        $data['guia'] = $guia;
        $data['detalle'] = $detalle;
        $data['comprobantes'] = $comprobantes;
        $data['empresa'] = $empresa;
        $data['qr_texto'] = $qrTexto;
        $data['qr_url'] = base_url('uploads/qr/' . $qrFileName);

        $this->load->view('almacen/guiaremitente/print', $data);
    }    

    public function create_desde_orden($orp_id) {
        $this->validar_permiso('grremitente_crear');

        $orden = $this->Orden_pedido_model->obtener_para_guia($orp_id);

        if (!$orden) {
            show_404();
        }

        $detalle = $this->Orden_pedido_model->obtener_detalle_para_guia($orp_id);

        if (empty($detalle)) {
            $this->session->set_flashdata('error', 'La orden no tiene saldo pendiente para generar guía');
            redirect('ventas/orden_pedido');
        }

        $data['titulo']         = 'Nueva Guía desde Orden';
        $data['motivos']        = $this->Guiaremitente_model->listar_motivos();
        $data['clientes']       = array(); // no se usará autocomplete libre
        $data['origenes']       = $this->Guiaremitente_model->listar_origenes();
        $data['transportistas'] = $this->Guiaremitente_model->listar_transportistas();
        $data['vehiculos']      = $this->Guiaremitente_model->listar_vehiculos();
        $data['conductores']    = $this->Guiaremitente_model->listar_conductores();
        $data['unidades_medida'] = $this->Guiaremitente_model->listar_unidades_peso();

        $data['orden']          = $orden;
        $data['detalle_orden']  = $detalle;

        $this->layout('almacen/guiaremitente/create_desde_orden', $data);
    }  
 

    public function store_desde_orden($orp_id) {
        $this->validar_permiso('grremitente_crear');

        $orden = $this->Orden_pedido_model->obtener_para_guia($orp_id);

        if (!$orden) {
            show_404();
        }

        $this->form_validation->set_rules('motivo_traslado_id', 'Motivo de traslado', 'required');
        $this->form_validation->set_rules('um_peso_bruto_id', 'Unidad de peso bruto', 'required');
        $this->form_validation->set_rules('peso_bruto_carga', 'Peso bruto', 'required|numeric');
        $this->form_validation->set_rules('origen_id', 'Origen', 'required');
        $this->form_validation->set_rules('destino_id', 'Destino', 'required');
        $this->form_validation->set_rules('tipo_transporte', 'Tipo de transporte', 'required');
        $this->form_validation->set_rules('fecha_traslado', 'Fecha de traslado', 'required');

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

        $detalle_orpd_id        = $this->input->post('detalle_orpd_id');
        $detalle_producto_id    = $this->input->post('detalle_producto_id');
        $detalle_um_id          = $this->input->post('detalle_um_id');
        $detalle_cantidad       = $this->input->post('detalle_cantidad');

        if (empty($detalle_producto_id) || !is_array($detalle_producto_id)) {
            $this->session->set_flashdata('error', 'Debe agregar al menos un producto al detalle');
            redirect('almacen/guiaremitente/create_desde_orden/'.$orp_id);
        }

        $detalleGuardar = array();

        for ($i = 0; $i < count($detalle_producto_id); $i++) {
            if (empty($detalle_producto_id[$i])) {
                continue;
            }

            $orpdId         = isset($detalle_orpd_id[$i]) ? (int)$detalle_orpd_id[$i] : 0;
            $productoId     = (int)$detalle_producto_id[$i];
            $umId           = isset($detalle_um_id[$i]) ? (int)$detalle_um_id[$i] : 0;
            $cantidad       = isset($detalle_cantidad[$i]) ? (float)$detalle_cantidad[$i] : 0;

            if ($orpdId <= 0 || $productoId <= 0 || $umId <= 0 || $cantidad <= 0) {
                continue;
            }

            $detalleOrden = $this->db->where('id', $orpdId)->get('vt_orden_pedido_detalle')->row();

            if (!$detalleOrden) {
                continue;
            }

            $pendienteGuia = round((float)$detalleOrden->orpd_cantidad - (float)$detalleOrden->orpd_cantidad_guiada, 2);

            if ($cantidad > $pendienteGuia) {
                $this->session->set_flashdata('error', 'La cantidad a guiar no puede superar el saldo pendiente del ítem');
                redirect('almacen/guiaremitente/create_desde_orden/'.$orp_id);
            }

            $detalleGuardar[] = array(
                'orpd_id'       => $orpdId,
                'producto_id'   => $productoId,
                'um_id'         => $umId,
                'cantidad'      => round($cantidad, 2)
            );
        }

        if (empty($detalleGuardar)) {
            $this->session->set_flashdata('error', 'No hay detalle válido para guardar');
            redirect('almacen/guiaremitente/create_desde_orden/'.$orp_id);
        }

        $this->db->trans_begin();

        $tipoComprobante = $this->Guiaremitente_model->obtener_tipo_comprobante_guia();

        if (!$tipoComprobante) {
            $this->session->set_flashdata('error', 'No se encontró configuración del tipo de comprobante para guía de remisión remitente');
            redirect('almacen/guiaremitente/create_desde_orden/'.$orp_id);
        }

        $serie              = trim($tipoComprobante->serie);
        $correlativoActual  = (int)$tipoComprobante->correlativo_actual;
        $numero             = str_pad($correlativoActual, 8, '0', STR_PAD_LEFT);

        $cabecera = array(
            'serie'                     => $serie,
            'numero'                    => $numero,
            'fecha_emision'             => $this->input->post('fecha_emision', TRUE),
            'comercio_exterior'         => (int)$this->input->post('comercio_exterior'),
            'motivo_traslado_id'        => (int)$this->input->post('motivo_traslado_id'),
            'cliente_id'                => (int)$orden->cliente_id,
            'um_peso_bruto_id'          => (int)$this->input->post('um_peso_bruto_id'),
            'peso_bruto_carga'          => (float)$this->input->post('peso_bruto_carga'),
            'origen_id'                 => (int)$this->input->post('origen_id'),
            'destino_id'                => (int)$this->input->post('destino_id'),
            'tipo_transporte'           => $this->input->post('tipo_transporte', TRUE),
            'transbordo_programado'     => (int)$this->input->post('transbordo_programado'),
            'traslado_vehiculo'         => (int)$this->input->post('traslado_vehiculo'),
            'vehiculo_id'               => $this->input->post('vehiculo_id') ? (int)$this->input->post('vehiculo_id') : null,
            'conductor_id'              => $this->input->post('conductor_id') ? (int)$this->input->post('conductor_id') : null,
            'transportista_id'          => $this->input->post('transportista_id') ? (int)$this->input->post('transportista_id') : null,
            'fecha_traslado'            => date('Y-m-d H:i:s', strtotime($this->input->post('fecha_traslado', TRUE))),
            'retorno_envases_vacios'    => (int)$this->input->post('retorno_envases_vacios'),
            'retorno_vehiculo_vacio'    => (int)$this->input->post('retorno_vehiculo_vacio'),
            'observaciones'             => trim($this->input->post('observaciones', TRUE)),
            'estado_id'                 => 29,
            'created_by'                => $this->session->userdata('id')
        );

        $grId = $this->Guiaremitente_model->insertar($cabecera);

        if (!$grId) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'No se pudo guardar la guía');
            redirect('almacen/guiaremitente/create_desde_orden/'.$orp_id);
        }

        foreach ($detalleGuardar as $item) {
            $this->Guiaremitente_model->insertar_detalle(array(
                'gr_remitente_id'   => $grId,
                'producto_id'       => $item['producto_id'],
                'um_id'             => $item['um_id'],
                'cantidad'          => $item['cantidad']
            ));

            $this->Guiaremitente_model->insertar_orp_detalle(array(
                'gr_remitente_id'   => $grId,
                'orp_id'            => $orp_id,
                'orpd_id'           => $item['orpd_id'],
                'cantidad_guiada'   => $item['cantidad']
            ));
        }

        $this->Guiaremitente_model->insertar_estado(array(
            'gr_remitente_id'       => $grId,
            'estado_id'             => 29,
            'gr_remitente_fechaestado' => date('Y-m-d H:i:s'),
            'usuario_id'            => $this->session->userdata('id')
        ));


        $nuevoCorrelativo = $correlativoActual + 1;
        $this->Guiaremitente_model->actualizar_correlativo_tipo_comprobante($tipoComprobante->id, $nuevoCorrelativo);

         // Recalcular cantidad guiada en la OP
        $detallesOrden = $this->Orden_pedido_model->obtener_detalles_para_recalculo_guia($orp_id);

        foreach ($detallesOrden as $det) {
            $guiado = $this->Guiaremitente_model->obtener_total_guiado_detalle_orden($det->id);
            $this->Orden_pedido_model->actualizar_cantidad_guiada_detalle_desde_orden($det->id, $guiado);
        }

        $this->Orden_pedido_model->recalcular_estado_orden_por_guia($orp_id);

        if ($this->db->trans_status() === FALSE) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'No se pudo registrar la guía');
            redirect('almacen/guiaremitente/create_desde_orden/'.$orp_id);
        }

        $this->db->trans_commit();

        $this->session->set_flashdata('success', 'Guía generada correctamente: ' . $serie . '-' . $numero);
        redirect('almacen/guiaremitente');
    }
   

    public function store_desde_guia() {
        $this->validar_permiso('comprobante_crear');

        $guiasIds = $this->input->post('guias_ids');

        if (empty($guiasIds) || !is_array($guiasIds)) {
            $this->session->set_flashdata('error', 'Debe seleccionar al menos una guía');
            redirect('almacen/guiaremitente');
        }

        $guiasIds = array_map('intval', $guiasIds);

        $guias = $this->Guiaremitente_model->obtener_para_comprobante($guiasIds);

        if (empty($guias)) {
            $this->session->set_flashdata('error', 'No se encontraron guías válidas');
            redirect('almacen/guiaremitente');
        }

        $cliente_id = (int)$guias[0]->cliente_id;
        $orp_id     = (int)$guias[0]->orp_id;

        foreach ($guias as $g) {
            if ((int)$g->estado_id !== 29) {
                $this->session->set_flashdata('error', 'Solo se pueden facturar guías en estado EMITIDO');
                redirect('almacen/guiaremitente');
            }

            if ((int)$g->cliente_id !== $cliente_id || (int)$g->orp_id !== $orp_id) {
                $this->session->set_flashdata('error', 'Las guías deben pertenecer al mismo cliente y orden');
                redirect('almacen/guiaremitente');
            }
        }

        // ================= VALIDACIONES =================
        $this->form_validation->set_rules('comprobante_id', 'Tipo de comprobante', 'required');
        $this->form_validation->set_rules('fecha', 'Fecha', 'required');
        $this->form_validation->set_rules('fp_id', 'Forma de pago', 'required');

        if ($this->form_validation->run() == FALSE) {
            redirect('almacen/guiaremitente');
        }

        // ================= DETALLE =================
        $detalle_producto_id     = $this->input->post('detalle_producto_id');
        $detalle_descripcion     = $this->input->post('detalle_descripcion');
        $detalle_cantidad        = $this->input->post('detalle_cantidad');
        $detalle_precio          = $this->input->post('detalle_precio_unitario');
        $detalle_subtotal        = $this->input->post('detalle_subtotal');

        if (empty($detalle_producto_id)) {
            $this->session->set_flashdata('error', 'No hay detalle válido');
            redirect('almacen/guiaremitente');
        }

        $detalleGuardar = array();
        $total = 0;

        for ($i = 0; $i < count($detalle_producto_id); $i++) {

            if (empty($detalle_producto_id[$i])) continue;

            $cantidad   = (float)$detalle_cantidad[$i];
            $precio     = (float)$detalle_precio[$i];
            $subtotal   = (float)$detalle_subtotal[$i];

            if ($cantidad <= 0 || $precio < 0) continue;

            $detalleGuardar[] = array(
                'producto_id'       => (int)$detalle_producto_id[$i],
                'descripcion'       => $detalle_descripcion[$i],
                'cantidad'          => $cantidad,
                'precio_unitario'   => $precio,
                'subtotal'          => $subtotal
            );

            $total += $subtotal;
        }

        if (empty($detalleGuardar)) {
            $this->session->set_flashdata('error', 'Detalle inválido');
            redirect('almacen/guiaremitente');
        }

        // ================= INICIO TRANSACCIÓN =================
        $this->db->trans_begin();

        // ================= SERIE =================
        $tipo = $this->Comprobante_model->obtener_tipo_comprobante($this->input->post('comprobante_id'));

        if (!$tipo) {
            $this->session->set_flashdata('error', 'No existe configuración de comprobante');
            redirect('almacen/guiaremitente');
        }

        $serie = trim($tipo->serie);
        $correlativo = (int)$tipo->correlativo_actual;
        $numero = str_pad($correlativo, 8, '0', STR_PAD_LEFT);

        // ================= IGV =================
        $igv = $this->Comprobante_model->obtener_tributo_igv();
        $porcIgv = (float)$igv->valor_porcentual / 100;

        $subtotal = round($total / (1 + $porcIgv), 2);
        $montoIgv = round($total - $subtotal, 2);

        // ================= ANTICIPOS =================
        $anticipo = (float)$this->Comprobante_model->obtener_total_anticipos_orden($orp_id);

        $pagoNeto = $total - $anticipo;

        // ================= CABECERA =================
        $cabecera = array(
            'comprobante_id'  => (int)$this->input->post('comprobante_id'),
            'serie'           => $serie,
            'numero'          => $numero,
            'cliente_id'      => $cliente_id,
            'fecha'           => date('Y-m-d H:i:s', strtotime($this->input->post('fecha'))),
            'subtotal'        => $subtotal,
            'igv'             => $montoIgv,
            'total'           => $total,
            'anticipo'        => $anticipo,
            'pago_neto'       => $pagoNeto,
            'fp_id'           => (int)$this->input->post('fp_id'),
            'origen'          => $orp_id,
            'observaciones'   => $this->input->post('observaciones'),
            'estado_id'       => 1,
            'created_by'      => $this->session->userdata('id')
        );

        $comprobId = $this->Comprobante_model->insertar($cabecera);

        if (!$comprobId) {
            $this->db->trans_rollback();
            redirect('almacen/guiaremitente');
        }

        // ================= DETALLE =================
        foreach ($detalleGuardar as $item) {
            $this->Comprobante_model->insertar_detalle(array(
                'comprob_id'        => $comprobId,
                'producto_id'       => $item['producto_id'],
                'descripcion'       => $item['descripcion'],
                'cantidad'          => $item['cantidad'],
                'precio_unitario'   => $item['precio_unitario'],
                'subtotal'          => $item['subtotal']
            ));
        }

        // ================= RELACIÓN GUÍA =================
        foreach ($guiasIds as $grId) {

            $this->Guiaremitente_model->insertar_comprobante_relacion(array(
                'gr_remitente_id' => $grId,
                'nrofactbolt_id'  => $comprobId
            ));

            $this->Guiaremitente_model->actualizar_estado($grId, 30);

            $this->Guiaremitente_model->insertar_estado(array(
                'gr_remitente_id' => $grId,
                'estado_id'       => 30,
                'gr_remitente_fechaestado' => date('Y-m-d H:i:s'),
                'usuario_id'      => $this->session->userdata('id')
            ));
        }

        // ================= CORRELATIVO =================
        $this->Comprobante_model->actualizar_correlativo($tipo->id, $correlativo + 1);

        // ================= ESTADO ORDEN =================
        $this->Orden_pedido_model->recalcular_estado_orden($orp_id);

        // ================= FIN =================
        if ($this->db->trans_status() === FALSE) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'Error al generar comprobante');
            redirect('almacen/guiaremitente');
        }

        $this->db->trans_commit();

        $this->session->set_flashdata('success', 'Comprobante generado: '.$serie.'-'.$numero);
        redirect('ventas/comprobante/ver/'.$comprobId);
    }


    public function anular($id) {
        $this->validar_permiso('grremitente_eliminar');
 
        $guia = $this->Guiaremitente_model->obtener($id);
 
        if (!$guia) {
            show_404();
        }
 
        if ((int)$guia->estado_id === 31) {
            $this->session->set_flashdata('error', 'La guía ya está anulada');
            redirect('almacen/guiaremitente');
        }
 
        if ((int)$guia->estado_id === 30) {
            $this->session->set_flashdata('error', 'No se puede anular una guía que ya tiene comprobante generado');
            redirect('almacen/guiaremitente');
        }
 
        if ($guia->envio_sunat == 1) {
            $this->session->set_flashdata('error', 'No se puede anular una guía ya enviada a SUNAT');
            redirect('almacen/guiaremitente');
        }
 
        $this->db->trans_begin();
 
        // Actualizar estado a ANULADO (31)
        $this->Guiaremitente_model->actualizar($id, array(
            'estado_id'  => 31,
            'updated_at' => date('Y-m-d H:i:s'),
            'updated_by' => $this->session->userdata('id')
        ));
 
        // Registrar en historial de estados
        $this->Guiaremitente_model->insertar_estado(array(
            'gr_remitente_id'          => $id,
            'estado_id'                => 31,
            'gr_remitente_fechaestado' => date('Y-m-d H:i:s'),
            'usuario_id'               => $this->session->userdata('id')
        ));
 
        if ($this->db->trans_status() === FALSE) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'No se pudo anular la guía');
            redirect('almacen/guiaremitente');
        }
 
        $this->db->trans_commit();
 
        $this->session->set_flashdata('success', 'Guía ' . $guia->serie . '-' . $guia->numero . ' anulada correctamente');
        redirect('almacen/guiaremitente');
    }


}