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

class ParteSalida_model extends CI_Model {

    public function listar() {
        return $this->db
            ->select('
                ps.*,
                a.nombre as almacen,
                COALESCE(c.razon_social, cc.razon_social) as cliente,
                CONCAT(IFNULL(e.apellidos,"")," ",IFNULL(e.nombres,"")) as empleado,
                u.usuario as usuario_creador,
                (SELECT COUNT(*) FROM lt_parte_salida_det d WHERE d.ps_id = ps.id) as total_items
            ')
            ->from('lt_parte_salida ps')
            ->join('mt_almacen a',          'a.id = ps.almacen_id')
            ->join('vt_cliente c',          'c.id = ps.cliente_id',          'left')
            ->join('vt_comprobante comp',   'comp.id = ps.comprob_id',       'left')
            ->join('vt_cliente cc',         'cc.id = comp.cliente_id',       'left')
            ->join('rh_empleado e',         'e.id = ps.empleado_id',         'left')
            ->join('usuarios u',            'u.id = ps.created_by',          'left')
            ->order_by('ps.id', 'DESC')
            ->get()
            ->result();
    }

    public function obtener($id) {
        return $this->db->where('id', $id)->get('lt_parte_salida')->row();
    }

    public function obtener_completo($id) {
        return $this->db
            ->select('
                ps.*,
                a.nombre as almacen,
                c.razon_social as cliente,
                c.nro_documento as cliente_documento,
                CONCAT(IFNULL(e.apellidos,"")," ",IFNULL(e.nombres,"")) as empleado,
                u.usuario as usuario_creador
            ')
            ->from('lt_parte_salida ps')
            ->join('mt_almacen a',   'a.id = ps.almacen_id')
            ->join('vt_cliente c',   'c.id = ps.cliente_id',  'left')
            ->join('rh_empleado e',  'e.id = ps.empleado_id', 'left')
            ->join('usuarios u',     'u.id = ps.created_by',  'left')
            ->where('ps.id', $id)
            ->get()
            ->row();
    }

    public function obtener_detalle($ps_id) {
        return $this->db
            ->select('
                d.*,
                p.codigo as producto_codigo,
                p.nombre as producto_nombre,
                p.maneja_stock,
                um.abreviado as unidad_abreviado
            ')
            ->from('lt_parte_salida_det d')
            ->join('vt_producto p',       'p.id = d.producto_id')
            ->join('mt_unidad_medida um', 'um.id = p.um_id_venta', 'left')
            ->where('d.ps_id', $ps_id)
            ->order_by('d.id', 'ASC')
            ->get()
            ->result();
    }

    public function insertar_cabecera($data) {
        $this->db->insert('lt_parte_salida', $data);
        return $this->db->insert_id();
    }

    public function insertar_detalle_batch($data) {
        return $this->db->insert_batch('lt_parte_salida_det', $data);
    }

    public function anular($id, $usuario_id) {
        return $this->db->where('id', $id)->update('lt_parte_salida', array(
            'estado'     => 0,
            'updated_at' => date('Y-m-d H:i:s'),
            'updated_by' => $usuario_id
        ));
    }

    // ---------------------------------------------------------------
    // STOCK - DESCONTAR Y REVERTIR
    // ---------------------------------------------------------------
    public function descontar_stock($producto_id, $almacen_id, $cantidad) {
        $registro = $this->db
            ->where('producto_id', $producto_id)
            ->where('almacen_id', $almacen_id)
            ->get('vt_producto_almacen')
            ->row();

        if (!$registro) return;

        $nuevo_stock = max(0, (float)$registro->cantidad_stock - (float)$cantidad);

        $this->db->where('producto_id', $producto_id)
                 ->where('almacen_id', $almacen_id)
                 ->update('vt_producto_almacen', array(
                     'cantidad_stock' => $nuevo_stock,
                     'updated_at'     => date('Y-m-d H:i:s'),
                     'updated_by'     => $this->session->userdata('id')
                 ));
    }

    public function revertir_stock($producto_id, $almacen_id, $cantidad) {
        $registro = $this->db
            ->where('producto_id', $producto_id)
            ->where('almacen_id', $almacen_id)
            ->get('vt_producto_almacen')
            ->row();

        if (!$registro) return;

        $nuevo_stock = (float)$registro->cantidad_stock + (float)$cantidad;

        $this->db->where('producto_id', $producto_id)
                 ->where('almacen_id', $almacen_id)
                 ->update('vt_producto_almacen', array(
                     'cantidad_stock' => $nuevo_stock,
                     'updated_at'     => date('Y-m-d H:i:s'),
                     'updated_by'     => $this->session->userdata('id')
                 ));
    }

    // ---------------------------------------------------------------
    // AUXILIARES
    // ---------------------------------------------------------------
    public function listar_almacenes() {
        return $this->db->where('estado', 1)->order_by('nombre', 'ASC')->get('mt_almacen')->result();
    }

    public function listar_empleados() {
        return $this->db
            ->select('id, apellidos, nombres')
            ->where('estado', 1)
            ->order_by('apellidos', 'ASC')
            ->get('rh_empleado')
            ->result();
    }

    public function buscar_cliente($term) {
        $this->db->select('id, razon_social, nro_documento');
        $this->db->from('vt_cliente');
        $this->db->where('estado', 1);
        $this->db->group_start();
        $this->db->like('razon_social', $term);
        $this->db->or_like('nro_documento', $term);
        $this->db->group_end();
        $this->db->limit(20);
        return $this->db->get()->result();
    }

    public function buscar_producto($term, $almacen_id = null) {
        $this->db->select('
            p.id, p.codigo, p.nombre, p.maneja_stock,
            um.abreviado as unidad_abreviado,
            IFNULL(pa.cantidad_stock, 0) as cantidad_stock,
            p.precio_unidad
        ');
        $this->db->from('vt_producto p');
        $this->db->join('mt_unidad_medida um', 'um.id = p.um_id_venta', 'left');
        if ($almacen_id) {
            $this->db->join('vt_producto_almacen pa',
                'pa.producto_id = p.id AND pa.almacen_id = ' . (int)$almacen_id, 'left');
        } else {
            $this->db->join('vt_producto_almacen pa', 'pa.producto_id = p.id', 'left');
        }
        $this->db->where('p.estado', 1);
        $this->db->where('p.activo_venta', 1);
        $this->db->group_start();
        $this->db->like('p.codigo', $term);
        $this->db->or_like('p.nombre', $term);
        $this->db->group_end();
        $this->db->limit(20);
        return $this->db->get()->result();
    }

    // Crear parte de salida desde comprobante (llamado desde módulo ventas)
    public function crear_desde_comprobante($comprob_id, $almacen_id, $cliente_id, $fecha, $usuario_id) {
        // Obtener detalle del comprobante
        $detalle = $this->db
            ->select('d.*, p.nombre, p.maneja_stock, um.abreviado as unidad_abreviado')
            ->from('vt_comprobante_detalle d')
            ->join('vt_producto p',       'p.id = d.producto_id')
            ->join('mt_unidad_medida um', 'um.id = p.um_id_venta', 'left')
            ->where('d.comprob_id', $comprob_id)
            ->get()->result();

        if (empty($detalle)) return false;

        $cabecera = array(
            'tiposalida'   => 'V',
            'fecha'        => $fecha,
            'almacen_id'   => $almacen_id,
            'cliente_id'   => $cliente_id,
            'comprob_id'   => $comprob_id,
            'estado'       => 1,
            'created_by'   => $usuario_id
        );

        $this->db->insert('lt_parte_salida', $cabecera);
        $ps_id = $this->db->insert_id();

        if (!$ps_id) return false;

        $detalleInsert = array();
        foreach ($detalle as $item) {
            $detalleInsert[] = array(
                'ps_id'          => $ps_id,
                'producto_id'    => $item->producto_id,
                'detalle'        => $item->descripcion,
                'cantidad'       => $item->cantidad,
                'precio_unitario'=> $item->precio_unitario,
                'subtotal'       => $item->subtotal
            );

            // Descontar stock
            if ($item->maneja_stock) {
                $this->descontar_stock($item->producto_id, $almacen_id, $item->cantidad);
            }
        }

        $this->db->insert_batch('lt_parte_salida_det', $detalleInsert);

        return $ps_id;
    }
}