<?php Session::init(); ?>
<?php
require_once 'models/kardex_model.php';
class Inventario_Model extends Model
{
	public function __construct()
	{
		parent::__construct();
	}

    public function Responsable()
    {
        try
        {      
            return $this->db->selectAll('SELECT * FROM tm_usuario WHERE id_usu <> 1 GROUP BY dni');
        }
        catch(Exception $e)
        {
            die($e->getMessage());
        }
    }
	
    /* AJUSTE DE STOCK */
    public function ajuste_list()
    {
        try
        {
            $ifecha = date('Y-m-d',strtotime($_POST['ifecha']));
            $ffecha = date('Y-m-d',strtotime($_POST['ffecha']));

            $stm = $this->db->prepare("SELECT i.*,IF(i.id_tipo=3,'ENTRADA','SALIDA') AS tipo, CONCAT(u.nombres,' ',u.ape_paterno,' ',u.ape_materno) AS responsable FROM tm_inventario_entsal AS i INNER JOIN tm_usuario AS u ON i.id_responsable = u.id_usu WHERE ((DATE_FORMAT(i.fecha,'%Y-%m-%d')) >= ? AND (DATE_FORMAT(i.fecha,'%Y-%m-%d')) <= ?)");
            $stm->execute(array($ifecha,$ffecha));
            $c = $stm->fetchAll(PDO::FETCH_OBJ);
            $data = array("data" => $c);
            $json = json_encode($data);
            echo $json; 
        }
        catch(Exception $e)
        {
            die($e->getMessage());
        }
    }

    public function ajuste_crud_create(array $data)
{
    // Asegurarnos de que PDO lance excepciones
    $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $messages = [];
    try {
        date_default_timezone_set($_SESSION["zona_horaria"]);
        setlocale(LC_ALL, "es_ES@euro", "es_ES", "esp");
        $fecha = date("Y-m-d H:i:s");

        // 1) Inserto cabecera
        $sql = "INSERT INTO tm_inventario_entsal
                   (id_tipo,id_usu,id_responsable,motivo,fecha)
                VALUES (?,?,?,?,?)";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([
            $data['id_tipo'],
            Session::get('usuid'),
            $data['id_responsable'],
            $data['motivo'],
            $fecha
        ]);

        
        $messages[] = "Registro tm_inventario_entsal creado, ID = " . $this->db->lastInsertId();

        $idEntSal = $this->db->lastInsertId();

        // 2) Recorro detalle
        foreach ($data['items'] as $d) {
            // 2.1) Inserto en tm_inventario
            $sql = "INSERT INTO tm_inventario
                       (id_tipo_ope,id_ope,id_tipo_ins,id_ins,cos_uni,cant,fecha_r)
                    VALUES (?,?,?,?,?,?,?)";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([
                $data['id_tipo'],
                $idEntSal,
                $d['id_tipo_ins_insumo'],
                $d['id_ins_insumo'],
                $d['precio_insumo'],
                $d['cantidad_insumo'],
                $fecha
            ]);


            
            // 2.2) Determino operación y tabla
            $oper   = ($data['id_tipo'] == 3) ? '+' : '-';

            if ($d['id_tipo_ins_insumo'] == 1) {
                $tabla = 'tm_insumo';
                $colId = 'id_ins';
            } else {
                $tabla = 'tm_producto_pres';
                $colId = 'id_pres';
            }

            $stockQuery = $this->db->query("
                    SELECT stock 
                    FROM {$tabla} 
                    WHERE {$colId} = {$d['id_ins_insumo']}"
                )->fetch(PDO::FETCH_OBJ);


            $dataKardex = array(
                'tipo_kardex' => ($data['id_tipo'] == 4) ? 2 : 3, // 2=salida, 3=entrada
                'presentacion_id' => $d['id_ins_insumo'],   // ID de la presentación
                'tipo_presentacion' =>$d['id_tipo_ins_insumo'] == 1 ? 2 : 1, // 1=priducto, 2=insumo presentación 
                'cantidad' => $d['cantidad_insumo'],         // Cantidad que ingresa
                'costo_unitario' => $d['precio_insumo'],   // Costo por unidad
                'serie_documento' => "",
                'numero_documento' => "",
                'tipo_documento' => "",             // Tipo documento
                'stock' => $oper == '+' ? $stockQuery->stock + $d['cantidad_insumo'] :  $stockQuery->stock - $d['cantidad_insumo'],             // Tipo documento
                'kardex' => $d['precio_insumo'],             // Tipo documento
                'estado' => 'activo'                    // Estado del registro
            );


            $this->registrarKardex($dataKardex);
  
            $messages[] = "tm_inventario: fila insertada para insumo/producto {$d['id_ins_insumo']}";

            // 2.3) Actualizo stock y compruebo filas afectadas
            $rows = $this->updateStock(
                (int)$d['id_ins_insumo'],
                (int)$d['cantidad_insumo'],
                $tabla,
                $colId,
                $oper
            );

            $messages[] = "Stock actualizado en {$tabla} (ID={$d['id_ins_insumo']}), filas afectadas: {$rows}";
        }

        return [
            'status'   => 'success',
            'messages' => $messages
        ];
    }
    catch (\Exception $e) {
        return [
            'status'   => 'error',
            'error'    => $e->getMessage(),
            'messages' => $messages
        ];
    }
}


public function registrarKardex(array $data): array {
  $this->db->beginTransaction();

  // 2.1 Guardas tu cabecera/detalle de data aquí...
  // $this->insertCabecera($data);
  // $this->insertDetalle($data['items']);

  $concepto = $data['tipo_kardex'] === 3 ? 'Entrada por ajuste' : 'Salida por ajuste';

  // 2.2 Construyes el payload para kardex
  $payloadKardex = [
    'id_usuario'       => Session::get('usuid'),
    'tipo_kardex'      => $data['tipo_kardex'],
    'tipo_envio_sunat' => 'prueba',
    'id_presentacion'  => (int)$data['presentacion_id'],
    'tipo_presentacion' => (int) $data['tipo_presentacion'],
    'cantidad_entrada' => $data['tipo_kardex'] === 3 ? $data['cantidad'] : 0,
    'cantidad_salida' => $data['tipo_kardex'] === 2 ? $data['cantidad'] : 0,
    'costo_unitario'   => $data['costo_unitario'],
    'costo_total' => (float) $data['costo_unitario'] * (float) $data['cantidad'],
    'concepto'         => $concepto,
    'serie_documento'  => $data['serie'] ?? null,
    'numero_documento' => $data['numero'] ?? null,
    'tipo_documento'   => null,
    'stock'            => $data['stock'] ?? '0',
    'estado'           => 'activo',
  ];

  $kardex = new Kardex(); // comparte el mismo PDO
  $out = $kardex->insert($payloadKardex);
  if (!$out['ok']) {
    $this->db->rollBack();
    return $out; // envelope con error (VALIDATION_ERROR / DB_ERROR, etc.)
  }
  $this->db->commit();

  return ['ok' => true];
}


    private function updateStock(int $id, int $cantidad, string $tabla, string $colId, string $oper): int
{
    $sql = "UPDATE {$tabla}
               SET stock = stock {$oper} :cantidad
             WHERE {$colId} = :id";

    $stmt = $this->db->prepare($sql);
    $stmt->bindValue(':cantidad', $cantidad, PDO::PARAM_INT);
    $stmt->bindValue(':id',       $id,       PDO::PARAM_INT);
    $stmt->execute();

    // Comprobamos errores en la ejecución
    $error = $stmt->errorInfo();
    if ($error[0] !== '00000') {
        throw new \RuntimeException(
            "Error SQLSTATE {$error[0]}: {$error[2]}"
        );
    }

    // Verificamos que al menos 1 fila se haya modificado
    $rowCount = $stmt->rowCount();
    if ($rowCount === 0) {
        throw new \RuntimeException(
            "No se modificó stock en {$tabla} para registro ID={$id}."
        );
    }

    return $rowCount;
}

    public function ajuste_det($data)
    {
        try
        {
            $stm = $this->db->prepare("SELECT * FROM tm_inventario WHERE id_tipo_ope = ? AND id_ope = ?");
            $stm->execute(array($data['id_tipo'], $data['id_es']));
            $c = $stm->fetchAll(PDO::FETCH_OBJ);
            foreach($c as $k => $d)
            {
                $c[$k]->{'Producto'} = $this->db->query("SELECT * FROM v_insprod WHERE id_tipo_ins = ".$d->id_tipo_ins."  AND id_ins = ".$d->id_ins)
                    ->fetch(PDO::FETCH_OBJ);
            }
            return $c;
        }
        catch(Exception $e)
        {
            die($e->getMessage());
        }
    }

    public function ajuste_delete($data)
    {
        try 
        {
            $consulta = "call usp_invESAnular( :flag, :id_es, :id_tipo);";
            $arrayParam =  array(
                ':flag' => 1,
                ':id_es' => $data['id_es'],
                ':id_tipo' => $data['id_tipo']
            );
            $st = $this->db->prepare($consulta);
            $st->execute($arrayParam);
            $row = $st->fetch(PDO::FETCH_ASSOC);
            return $row;
        } catch (Exception $e) 
        {
            die($e->getMessage());
        }
    }

    public function ajuste_insumo_buscar($data)
{
    try {
        $cadena = "%{$data['cadena']}%";

        $sql = "
            SELECT * FROM v_insprod
            WHERE (ins_cod LIKE ? OR ins_nom LIKE ?)
              AND est_b COLLATE utf8mb4_unicode_ci = 'a'
              AND est_c COLLATE utf8mb4_unicode_ci = 'a'
              AND (crt_stock = '1' OR ins_rec = '1')
            ORDER BY ins_nom
            LIMIT 5
        ";

        $stm = $this->db->prepare($sql);
        $stm->execute([$cadena, $cadena]);

        return $stm->fetchAll(PDO::FETCH_OBJ);
    } catch (Exception $e) {
        die("Error en ajuste_insumo_buscar: " . $e->getMessage());
    }
}


    public function combomedida($data)
    {
        try
        {   
            $stmm = $this->db->prepare("SELECT * FROM tm_tipo_medida WHERE grupo = ? OR grupo = ?");
            $stmm->execute(array($data['va1'],$data['va2']));
            $var = $stmm->fetchAll(PDO::FETCH_ASSOC);
            foreach($var as $v){
                echo '<option value="'.$v['id_med'].'">'.$v['descripcion'].'</option>';
            }
        }
        catch(Exception $e)
        {
            die($e->getMessage());
        }
    }

    /* STOCK */
    // public function stock_list($data)
    // {
    //     try
    //     {
    //         $stm = $this->db->prepare("SELECT * FROM v_stock WHERE id_tipo_ins LIKE ? AND debajo_stock LIKE ?");
    //         $stm->execute(array($data['tipo_ins'],$data['stock_min']));
    //         $c = $stm->fetchAll(PDO::FETCH_OBJ);
    //         foreach($c as $k => $d)
    //         {
    //             $c[$k]->{'Producto'} = $this->db->query("SELECT * FROM v_insprod WHERE id_tipo_ins = ".$d->id_tipo_ins." AND id_ins = ".$d->id_ins)
    //                 ->fetch(PDO::FETCH_OBJ);
                
    //         }
    //         $data = array("data" => $c);
    //         $json = json_encode($data);
    //         echo $json; 
    //     }
    //     catch(Exception $e)
    //     {
    //         die($e->getMessage());
    //     }
    // }

    public function stock_list($data)
{
    try {
        $stm = $this->db->prepare("SELECT * FROM v_stock WHERE id_tipo_ins LIKE ? AND debajo_stock LIKE ?");
        $stm->execute(array($data['tipo_ins'], $data['stock_min']));
        $c = $stm->fetchAll(PDO::FETCH_OBJ);

        foreach($c as $k => $d)
        {
            // Agrega el producto (como ya lo tenías)
            $c[$k]->{'Producto'} = $this->db->query("
                SELECT * FROM v_insprod 
                WHERE id_tipo_ins = {$d->id_tipo_ins} AND id_ins = {$d->id_ins}
            ")->fetch(PDO::FETCH_OBJ);

            // Agrega el stock según el tipo
            if ($d->id_tipo_ins == 1) {
                // Insumo
                $c[$k]->{'Stock'} = $this->db->query("
                    SELECT stock FROM tm_insumo WHERE id_ins = {$d->id_ins}
                ")->fetch(PDO::FETCH_OBJ);
            } elseif ($d->id_tipo_ins == 2) {
                // Producto presentación
                $c[$k]->{'Stock'} = $this->db->query("
                    SELECT stock FROM tm_producto_pres WHERE id_pres = {$d->id_ins}
                ")->fetch(PDO::FETCH_OBJ);
            } else {
                // Por si hay otro tipo no manejado
                $c[$k]->{'Stock'} = null;
            }
        }

        $data = array("data" => $c);
        echo json_encode($data);
    } catch(Exception $e) {
        die($e->getMessage());
    }
}


    /* KARDEX VALORIZADO */
    public function kardex_list()
    {
        try
        {
            $tipo_ip = $_POST['tipo_ip'];
            $id_ip = $_POST['id_ip'];
            $ifecha = date('Y-m-d',strtotime($_POST['ifecha']));
            $ffecha = date('Y-m-d',strtotime($_POST['ffecha']));

            $stm = $this->db->prepare("SELECT id_inv,id_tipo_ope,id_ope,id_tipo_ins,id_ins,cos_uni,cant,fecha_r,estado,
                    IF(id_tipo_ope = 1 OR id_tipo_ope = 3,FORMAT(cant,6),0) AS cantidad_entrada, 
                    IF(id_tipo_ope = 1 OR id_tipo_ope = 3,cos_uni,0) AS costo_entrada, 
                    IF(id_tipo_ope = 1 OR id_tipo_ope = 3,(cant*cos_uni),0) AS total_entrada, 
                    IF(id_tipo_ope = 2 OR id_tipo_ope = 4,FORMAT(cant,6),0) AS cantidad_salida, 
                    IF(id_tipo_ope = 2 OR id_tipo_ope = 4,cos_uni,'-') AS costo_salida, 
                    IF(id_tipo_ope = 2 OR id_tipo_ope = 4,(cant*cos_uni),0) AS total_salida
                FROM tm_inventario WHERE id_tipo_ins = ? AND id_ins = ? AND (date(fecha_r) >= ? AND date(fecha_r) <= ?)");
            $stm->execute(array($tipo_ip,$id_ip,$ifecha,$ffecha));
            $c = $stm->fetchAll(PDO::FETCH_OBJ);
            foreach($c as $k => $d)
            {
                $c[$k]->{'Precio'} = $this->db->query("SELECT ROUND(AVG(cos_uni),2) AS cos_pro FROM tm_inventario WHERE id_tipo_ins = ".$d->id_tipo_ins." AND id_ins = ".$d->id_ins)
                    ->fetch(PDO::FETCH_OBJ);

                $c[$k]->{'Medida'} = $this->db->query("SELECT ins_med FROM v_insprod WHERE id_tipo_ins = ".$d->id_tipo_ins." AND id_ins = ".$d->id_ins)
                    ->fetch(PDO::FETCH_OBJ);

                $c[$k]->{'Stock'} = $this->db->query("SELECT SUM(ent - sal) AS total FROM v_stock WHERE id_ins = ".$id_ip)
                    ->fetch(PDO::FETCH_OBJ);

                if($d->id_tipo_ope == 1){
                    $c[$k]->{'Comp'} = $this->db->query("SELECT serie_doc AS ser_doc,num_doc AS nro_doc,desc_td FROM v_compras WHERE id_compra = ".$d->id_ope)
                    ->fetch(PDO::FETCH_OBJ);
                } else if($d->id_tipo_ope == 2){
                    $c[$k]->{'Comp'} = $this->db->query("SELECT ser_doc,nro_doc,desc_td FROM v_ventas_con WHERE id_ven = ".$d->id_ope)
                    ->fetch(PDO::FETCH_OBJ);
                } else if($d->id_tipo_ope == 3 OR $d->id_tipo_ope == 4){
                    $c[$k]->{'Comp'} = $this->db->query("SELECT i.motivo, CONCAT(u.nombres,' ',u.ape_paterno,' ',u.ape_materno) AS responsable FROM tm_inventario_entsal AS i INNER JOIN tm_usuario AS u ON i.id_responsable = u.id_usu WHERE i.id_es = ".$d->id_ope)
                    ->fetch(PDO::FETCH_OBJ);
                }
            }
            
            $data = array("data" => $c);
            $json = json_encode($data);
            echo $json; 
        }
        catch(Exception $e)
        {
            die($e->getMessage());
        }
    }

    public function ComboInsumoProducto($data)
    {
        try
        {   
            $stmm = $this->db->prepare("SELECT id_ins,ins_cod,ins_nom,ins_cat FROM v_insprod WHERE id_tipo_ins = ? AND est_b = 'a' AND est_c = 'a'");
            $stmm->execute(array($data['id_tipo_ins']));
            $var = $stmm->fetchAll(PDO::FETCH_ASSOC);
            foreach($var as $v){
                echo '<option value="'.$v['id_ins'].'">'.$v['ins_cod'].' | '.$v['ins_cat'].' | '.$v['ins_nom'].'</option>';
            }
        }
        catch(Exception $e)
        {
            die($e->getMessage());
        }
    }

    public function impresion_stock($data)
    {
        try
        {

            $stm = $this->db->prepare("SELECT * FROM v_stock WHERE id_tipo_ins LIKE ? AND debajo_stock LIKE ?");
            $stm->execute(array($data['tipo_ins'],$data['stock_min']));
            $c = $stm->fetchAll(PDO::FETCH_OBJ);
            foreach($c as $k => $d)
            {
                $c[$k]->{'Producto'} = $this->db->query("SELECT * FROM v_insprod WHERE id_tipo_ins = ".$d->id_tipo_ins." AND id_ins = ".$d->id_ins)
                    ->fetch(PDO::FETCH_OBJ);
            }
            return $c;
            // $data = array("data" => $c);
            // $json = json_encode($data);
            // echo $json; 
        }
        catch(Exception $e)
        {
            die($e->getMessage());
        }
    }


}