<?php
// api/buscadorcotizaciones.php

session_start();
include '../../includes/session_control.php';

header('Content-Type: application/json; charset=UTF-8');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Pragma: no-cache');
header('Expires: 0');

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
  http_response_code(405);
  echo json_encode([]);
  exit;
}
if (!isset($_SESSION['user'])) {
  http_response_code(401);
  echo json_encode([]);
  exit;
}

require __DIR__ . '/_node.php';

$token = cpn_node_token_or_fail();
$base = cpn_node_api_base();
$url = $base . '/api/cotizaciones/buscador';

$payload = [
  'inventarioDesde' => $_POST['inventarioDesde'] ?? 1,
  'mostrarSinStock' => $_POST['mostrarSinStock'] ?? 0,
  'referenciaCPN' => $_POST['referenciaCPN'] ?? '',
  'searchTerm' => $_POST['searchTerm'] ?? '',

  'descuentoAntesImpuestosDesde' => $_POST['descuentoAntesImpuestosDesde'] ?? '',
  'descuentoAntesImpuestosHasta' => $_POST['descuentoAntesImpuestosHasta'] ?? '',
  'descuentoDesde' => $_POST['descuentoDesde'] ?? '',
  'descuentoHasta' => $_POST['descuentoHasta'] ?? '',
  'precioMarcaAntesImpuestosDesde' => $_POST['precioMarcaAntesImpuestosDesde'] ?? '',
  'precioMarcaAntesImpuestosHasta' => $_POST['precioMarcaAntesImpuestosHasta'] ?? '',
  'precioMarcaDesde' => $_POST['precioMarcaDesde'] ?? '',
  'precioMarcaHasta' => $_POST['precioMarcaHasta'] ?? '',

  'precioFinalMarca' => $_POST['precioFinalMarca'] ?? 0,
  'tecnicaTipoRango' => $_POST['tecnicaTipoRango'] ?? '',
  'idServicio' => $_POST['idServicio'] ?? null,

  'orderBy' => $_POST['orderBy'] ?? 'referenciaCPN',
  'orderDir' => $_POST['orderDir'] ?? 'ASC',
  'page' => $_POST['page'] ?? 1,
  'pageSize' => $_POST['pageSize'] ?? 30,
];

$r = cpn_node_request('POST', $url, $token, $payload);
if (!isset($r['ok']) || $r['ok'] !== true) {
  echo json_encode([]);
  exit;
}

echo json_encode($r['data'] ?? []);
exit;

// Helper para valores de POST
$P = function ($k, $d = null) {
  return isset($_POST[$k]) ? $_POST[$k] : $d;
};

$searchTerm  = trim($P('searchTerm', ''));
$referencia  = trim($P('referenciaCPN', ''));
$invDesde    = max(1, (int)$P('inventarioDesde', 1));
$page        = max(1, (int)$P('page', 1));
$pageSize    = max(1, (int)$P('pageSize', 9999)); // casi “sin límite”
$offset      = ($page - 1) * $pageSize;

// Filtros numéricos
$numFiltros = [
  'descuentoDesde',
  'descuentoHasta',
  'descuentoAntesImpuestosDesde',
  'descuentoAntesImpuestosHasta',
  'precioMarcaDesde',
  'precioMarcaHasta',
  'precioMarcaAntesImpuestosDesde',
  'precioMarcaAntesImpuestosHasta'
];
$POST = [];
foreach ($numFiltros as $f) {
  $val = trim($P($f, ''));
  // Si vino vacío o no viene, lo dejo en null para NO agregar “HAVING”
  $POST[$f] = ($val !== '') ? (float)$val : null;
}

// Precio de marca y técnica
$precioFinalMarca  = (float)$P('precioFinalMarca', 0);
$precioFinalMarcaI = $precioFinalMarca * 1.19;

// Para bind_param
$bindVals  = [];
$bindTypes = '';

// -------------------------------------------------
//  Selección base (igual que original + GROUP BY)
// -------------------------------------------------
// … código anterior …

// Construimos el SELECT base
$sql = "
  SELECT
    v.referenciaCPN,
    REPLACE(iv.linkImagen,'J:/images/','https://sistema.compranet.com.co/images/') AS urlImagen,
    CONCAT(p.nombre,' - ',v.txtColor) AS nombreColor,
    v.inventario,
    v.id                 AS idVariacion,
    v.wp_id              AS idwpProductoVariacion,
    p.urlExterna,
    CONCAT('https://compranet.com.co/?p=',v.wp_id) AS linkProducto,

/* 1) Precio antes de IVA con escala o fallback */
COALESCE(
  (SELECT edv.PVPantesImpuestos
     FROM tb_escala_descuentos_variaciones edv
    WHERE edv.idVariacion = v.id
      AND edv.cantidadRequerida <= ?
    ORDER BY edv.cantidadRequerida DESC
    LIMIT 1
  ),
  LEAST(
    IFNULL(NULLIF(v.PVPantesImpuestos, 0), 999999),
    IFNULL(NULLIF(v.PVPreducidoantesImpuestos, 0), 999999)
  )
) AS descuentoPVPantesImpuestos,


/* 2) Precio con IVA (sin marca) con escala o fallback */
COALESCE(
  (SELECT edv.PVP
     FROM tb_escala_descuentos_variaciones edv
    WHERE edv.idVariacion = v.id
      AND edv.cantidadRequerida <= ?
    ORDER BY edv.cantidadRequerida DESC
    LIMIT 1
  ),
  LEAST(
    IFNULL(NULLIF(v.PVP, 0), 999999),
    IFNULL(NULLIF(v.PVPReducido, 0), 999999)
  )
) AS descuentoPVP,


/* 3) Nivel de la escala */
COALESCE(
  (SELECT edv.nombreEscala
     FROM tb_escala_descuentos_variaciones edv
    WHERE edv.idVariacion = v.id
      AND edv.cantidadRequerida <= ?
    ORDER BY edv.cantidadRequerida DESC
    LIMIT 1
  ),
  'Nivel Base'
) AS Nivel,


/* 4) Precio con marca antes de IVA */
(
  COALESCE(
    (SELECT edv.PVPantesImpuestos
       FROM tb_escala_descuentos_variaciones edv
      WHERE edv.idVariacion = v.id
        AND edv.cantidadRequerida <= ?
      ORDER BY edv.cantidadRequerida DESC
      LIMIT 1
    ),
    LEAST(
      IFNULL(NULLIF(v.PVPantesImpuestos, 0), 999999),
      IFNULL(NULLIF(v.PVPreducidoantesImpuestos, 0), 999999)
    )
  ) + ?
) AS precioMarcaAntesImpuestos,


/* 5) Precio con marca con IVA */
(
  COALESCE(
    (SELECT edv.PVP
       FROM tb_escala_descuentos_variaciones edv
      WHERE edv.idVariacion = v.id
        AND edv.cantidadRequerida <= ?
      ORDER BY edv.cantidadRequerida DESC
      LIMIT 1
    ),
    LEAST(
      IFNULL(NULLIF(v.PVP, 0), 999999),
      IFNULL(NULLIF(v.PVPReducido, 0), 999999)
    )
  ) + ?
) AS precioMarcaConImpuestos


  FROM tb_productos_variantes v
  JOIN tb_imagenes_variantes iv
    ON iv.idVariante = v.id
  JOIN tb_productos p
    ON p.id = v.idProducto
  WHERE v.PVPantesImpuestos > 0
    AND v.inventario > 0
    AND (v.referenciaCPN LIKE CONCAT('%', ?, '%') OR ? = '')
AND (
     v.referenciaCPN LIKE 'CPN-M%'
  OR p.wp_id > 0
)
";

// … después vienes a armar bind_param exactamente igual que antes …


// 1) Bind de invDesde y precioFinalMarca
$bindVals[]  = $invDesde;
$bindTypes .= 'i';
$bindVals[]  = $invDesde;
$bindTypes .= 'i';
$bindVals[]  = $invDesde;
$bindTypes .= 'i';
$bindVals[]  = $invDesde;
$bindTypes .= 'i';
$bindVals[]  = $precioFinalMarca;
$bindTypes .= 'd';
$bindVals[]  = $invDesde;
$bindTypes .= 'i';
$bindVals[]  = $precioFinalMarcaI;
$bindTypes .= 'd';
$bindVals[]  = $referencia;
$bindTypes .= 's';
$bindVals[]  = $referencia;
$bindTypes .= 's';

// 2) Si se ingresó searchTerm, agregamos las condiciones LIKE + SINÓNIMOS
$whereExtras = [];
if ($searchTerm !== '') {
  $words = preg_split('/\s+/', mb_strtolower($searchTerm, 'UTF-8'));
  $conds = [];
  foreach ($words as $w) {
    $w_esc = $conn->real_escape_string($w);
    $sins  = [$w_esc];
    $rs    = $conn->query("SELECT sinonimo 
                           FROM tb_terminos_busqueda
                           WHERE LOWER(REPLACE(valor,'í','i')) = '{$w_esc}'");
    while ($row = $rs->fetch_row()) {
      $sins[] = mb_strtolower($row[0], 'UTF-8');
    }
    $subConds = [];
    foreach ($sins as $s) {
      $like = '%' . $s . '%';
      // Para cada sinónimo agrego 5 condiciones LIKE
      $bindVals[] = $like;
      $bindTypes .= 's';
      $bindVals[] = $like;
      $bindTypes .= 's';
      $bindVals[] = $like;
      $bindTypes .= 's';
      $bindVals[] = $like;
      $bindTypes .= 's';
      $bindVals[] = $like;
      $bindTypes .= 's';
      $subConds[] = "(
        LOWER(p.nombre)       LIKE ?
        OR LOWER(v.txtColor)  LIKE ?
        OR LOWER(p.descripcion) LIKE ?
        OR LOWER(p.txtMedidas) LIKE ?
        OR LOWER(p.txtMaterial) LIKE ?
      )";
    }
    $conds[] = '(' . implode(' AND ', $subConds) . ')';
  }
  $whereExtras[] = '(' . implode(' AND ', $conds) . ')';
}

// 3) Filtros numéricos → cláusulas HAVING
$having = [];
$rangoMap = [
  ['descuentoDesde',               '>=', 'descuentoPVP'],
  ['descuentoHasta',               '<=', 'descuentoPVP'],
  ['descuentoAntesImpuestosDesde', '>=', 'descuentoPVPantesImpuestos'],
  ['descuentoAntesImpuestosHasta', '<=', 'descuentoPVPantesImpuestos'],
  ['precioMarcaDesde',             '>=', 'precioMarcaConImpuestos'],
  ['precioMarcaHasta',             '<=', 'precioMarcaConImpuestos'],
  ['precioMarcaAntesImpuestosDesde', '>=', 'precioMarcaAntesImpuestos'],
  ['precioMarcaAntesImpuestosHasta', '<=', 'precioMarcaAntesImpuestos'],
];
foreach ($rangoMap as list($key, $op, $alias)) {
  if ($POST[$key] !== null) {
    $having[]   = "$alias $op ?";
    $bindVals[] = $POST[$key];
    $bindTypes  .= 'd';
  }
}

// 4) Siempre filtrar stock mínimo: v.inventario >= invDesde
$whereExtras[] = 'v.inventario >= ?';
$bindVals[]   = $invDesde;
$bindTypes   .= 'i';

// Adjuntar cláusulas WHERE extras
if (!empty($whereExtras)) {
  $sql .= ' AND ' . implode(' AND ', $whereExtras);
}

// Adjuntar cláusulas HAVING
if (!empty($having)) {
  $sql .= ' GROUP BY 
      v.referenciaCPN, 
      urlImagen, 
      nombreColor, 
      descuentoPVPantesImpuestos,
      descuentoPVP,
      v.inventario, 
      v.wp_id,
      Nivel,
      v.minVenta,
      v.multiploVenta,
      precioMarcaAntesImpuestos
    HAVING ' . implode(' AND ', $having);
} else {
  // Si no hay HAVING, igual necesitamos el GROUP BY para mantener coherencia con la versión original:
  $sql .= ' GROUP BY 
      v.referenciaCPN, 
      urlImagen, 
      nombreColor, 
      descuentoPVPantesImpuestos,
      descuentoPVP,
      v.inventario, 
      v.wp_id,
      Nivel,
      v.minVenta,
      v.multiploVenta,
      precioMarcaAntesImpuestos';
}

// 5) ORDER BY y paginación
$orderValid = [
  'referenciaCPN',
  'descuentoPVP',
  'descuentoPVPantesImpuestos',
  'precioMarcaConImpuestos',
  'precioMarcaAntesImpuestos',
  'inventario'
];
$orderBy  = in_array($P('orderBy', ''), $orderValid) ? $P('orderBy') : 'referenciaCPN';
$orderDir = strtoupper($P('orderDir', 'ASC')) === 'DESC' ? 'DESC' : 'ASC';

$sql .= " ORDER BY $orderBy $orderDir
           LIMIT ? OFFSET ?";
$bindVals[] = $pageSize;
$bindTypes .= 'i';
$bindVals[] = $offset;
$bindTypes .= 'i';

// Preparar y bind_param dinámico
$stmt = $conn->prepare($sql);
if (!$stmt) {
  http_response_code(500);
  echo json_encode(['error' => $conn->error]);
  exit;
}

// bind_param requiere referencias
$params = [];
$params[] = &$bindTypes;
for ($i = 0; $i < count($bindVals); $i++) {
  $params[] = &$bindVals[$i];
}
call_user_func_array([$stmt, 'bind_param'], $params);

// Ejecutar
$stmt->execute();
$res = $stmt->get_result();
$out = $res->fetch_all(MYSQLI_ASSOC);

echo json_encode($out);
exit;
