<?php
header('Content-Type: application/json; charset=utf-8');
session_start();

require_once '../Utilidades/Conexion_BD.php';
require_once '../Utilidades/Permisos.php';

if (!isset($_SESSION['usuario'])) {
  echo json_encode(['ok'=>false,'msg'=>'Sesión expirada']);
  exit;
}

$action = $_POST['action'] ?? $_GET['action'] ?? '';
$conn   = new Conexion_BD();
$cn     = $conn->getConnection();

function j($r){ echo json_encode($r, JSON_UNESCAPED_UNICODE); }

/**
 * Guarda la imagen enviada en $_FILES[$campo] dentro de
 * /Modelo/Archivos_Media/Repuestos/ y devuelve el nombre de archivo.
 * Si no se sube nada, devuelve el nombre anterior.
 */
function guardarImagenRepuesto(string $campo, string $nombreAnterior = '')
{
  if (
    !isset($_FILES[$campo]) ||
    $_FILES[$campo]['error'] !== UPLOAD_ERR_OK
  ) {
    // No se subió nada: conservar anterior
    return $nombreAnterior;
  }

  $tmpName = $_FILES[$campo]['tmp_name'];
  $origName = $_FILES[$campo]['name'];
  $ext = strtolower(pathinfo($origName, PATHINFO_EXTENSION));
  $permitidas = ['jpg','jpeg','png','gif','webp'];

  if (!in_array($ext, $permitidas)) {
    // Extensión no permitida, conservar anterior
    return $nombreAnterior;
  }

  // Carpeta física
  $carpeta = __DIR__ . '/../../Modelo/Archivos_Media/Repuestos/';
  if (!is_dir($carpeta)) {
    @mkdir($carpeta, 0775, true);
  }

  $nuevoNombre = 'rep_' . time() . '_' . mt_rand(1000,9999) . '.' . $ext;
  $destino = $carpeta . $nuevoNombre;

  if (move_uploaded_file($tmpName, $destino)) {
    // Si había una imagen anterior, la borramos (opcional)
    if ($nombreAnterior) {
      $rutaAnterior = $carpeta . $nombreAnterior;
      if (is_file($rutaAnterior)) {
        @unlink($rutaAnterior);
      }
    }
    return $nuevoNombre;
  }

  return $nombreAnterior;
}

switch($action){

  /* ==========================================================
   * LISTADO PRINCIPAL PARA DATATABLE
   * ========================================================== */
  case 'listar':
    $sql = "
      SELECT r.id,
             r.sku,
             r.nombre,
             COALESCE(c.nombre,'-')     AS categoria,
             u.abreviatura              AS um,
             COALESCE(a.nombre,'-')     AS almacen,
             COALESCE(p.nombre,'-')     AS proveedor,
             r.stock_actual,
             r.stock_min,
             r.costo_promedio,
             r.imagen
      FROM rep_repuestos r
      LEFT JOIN rep_categorias c ON c.id = r.id_categoria
      INNER JOIN rep_unidades u  ON u.id = r.id_unidad
      LEFT JOIN rep_almacenes a  ON a.id = r.id_almacen_default
      LEFT JOIN rep_proveedor p  ON p.id = r.id_proveedor
      ORDER BY r.nombre ASC
    ";
    $res  = $cn->query($sql);
    if (!$res) {
      j(['ok'=>false,'msg'=>'Error al listar: '.$cn->error]);
      break;
    }
    $rows = $res->fetch_all(MYSQLI_ASSOC);
    j(['ok'=>true,'data'=>$rows]);
  break;

  /* ==========================================================
   * SELECTS (CATEGORÍAS / UNIDADES / ALMACENES / PROVEEDORES)
   * ========================================================== */
  case 'listar_selects':
    // Categorías
    $resC = $cn->query("SELECT id, nombre FROM rep_categorias ORDER BY nombre");
    $cats = $resC ? $resC->fetch_all(MYSQLI_ASSOC) : [];

    // Unidades
    $resU = $cn->query("SELECT id, CONCAT(nombre,' (',abreviatura,')') AS texto FROM rep_unidades ORDER BY nombre");
    $ums  = $resU ? $resU->fetch_all(MYSQLI_ASSOC) : [];

    // Almacenes
    $resA = $cn->query("SELECT id, nombre FROM rep_almacenes ORDER BY nombre");
    $alms = $resA ? $resA->fetch_all(MYSQLI_ASSOC) : [];

    // Proveedores
    $resP = $cn->query("SELECT id, nombre FROM rep_proveedor ORDER BY nombre");
    $provs = $resP ? $resP->fetch_all(MYSQLI_ASSOC) : [];

    j([
      'ok'          => true,
      'categorias'  => $cats,
      'unidades'    => $ums,
      'almacenes'   => $alms,
      'proveedores' => $provs
    ]);
  break;

  /* ==========================================================
   * CREAR REPUESTO
   * ========================================================== */
  case 'crear':
    $sku        = trim($_POST['sku'] ?? '');
    $nombre     = trim($_POST['nombre'] ?? '');
    $id_prov    = ($_POST['id_proveedor']       !== '' ? (int)$_POST['id_proveedor']       : null);
    $id_cat     = ($_POST['id_categoria']       !== '' ? (int)$_POST['id_categoria']       : null);
    $id_um      = (int)($_POST['id_unidad']     ?? 0);
    $id_alm     = ($_POST['id_almacen_default'] !== '' ? (int)$_POST['id_almacen_default'] : null);
    $stockMin   = (int)($_POST['stock_min']     ?? 0);
    $stockMax   = (int)($_POST['stock_max']     ?? 0);

    // imagen_actual viene vacío en crear, pero lo usamos igual por compatibilidad
    $imagenActual = trim($_POST['imagen_actual'] ?? '');
    $nombreImagen = guardarImagenRepuesto('imagen', $imagenActual);

    if ($sku === '' || $nombre === '' || $id_um <= 0){
      j(['ok'=>false,'msg'=>'Completa SKU, Nombre y Unidad']); break;
    }

    $stmt = $cn->prepare("
      INSERT INTO rep_repuestos
      (sku, nombre, id_proveedor, id_categoria, id_unidad, id_almacen_default,
       stock_min, stock_max, stock_actual, costo_promedio, imagen)
      VALUES (?,?,?,?,?,?,?, ?, 0, 0, ?)
    ");
    if (!$stmt) {
      j(['ok'=>false,'msg'=>'Error en prepare: '.$cn->error]); break;
    }

    $stmt->bind_param(
      "ssiiiiiis",
      $sku,
      $nombre,
      $id_prov,
      $id_cat,
      $id_um,
      $id_alm,
      $stockMin,
      $stockMax,
      $nombreImagen
    );
    $ok = $stmt->execute();
    j(['ok'=>$ok, 'msg'=>$ok?'Repuesto creado correctamente':'No se pudo crear el repuesto']);
  break;

  /* ==========================================================
   * OBTENER REPUESTO POR ID
   * ========================================================== */
  case 'obtener':
    $id = (int)($_GET['id'] ?? 0);
    if ($id <= 0){ j(['ok'=>false,'msg'=>'ID inválido']); break; }
    $stmt = $cn->prepare("SELECT * FROM rep_repuestos WHERE id=?");
    $stmt->bind_param("i", $id);
    $stmt->execute();
    $res = $stmt->get_result();
    $row = $res ? $res->fetch_assoc() : null;
    if(!$row){ j(['ok'=>false,'msg'=>'Repuesto no encontrado']); break; }
    j(['ok'=>true,'data'=>$row]);
  break;

  /* ==========================================================
   * ACTUALIZAR REPUESTO
   * ========================================================== */
  case 'actualizar':
    $id        = (int)($_POST['id'] ?? 0);
    $sku       = trim($_POST['sku'] ?? '');
    $nombre    = trim($_POST['nombre'] ?? '');
    $id_prov   = ($_POST['id_proveedor']       !== '' ? (int)$_POST['id_proveedor']       : null);
    $id_cat    = ($_POST['id_categoria']       !== '' ? (int)$_POST['id_categoria']       : null);
    $id_um     = (int)($_POST['id_unidad']     ?? 0);
    $id_alm    = ($_POST['id_almacen_default'] !== '' ? (int)$_POST['id_almacen_default'] : null);
    $stockMin  = (int)($_POST['stock_min']     ?? 0);
    $stockMax  = (int)($_POST['stock_max']     ?? 0);

    // nombre anterior de la imagen (hidden en el form)
    $imagenActual = trim($_POST['imagen_actual'] ?? '');
    $nombreImagen = guardarImagenRepuesto('imagen', $imagenActual);

    if ($id <= 0 || $sku === '' || $nombre === '' || $id_um <= 0){
      j(['ok'=>false,'msg'=>'Datos incompletos']); break;
    }

    $stmt = $cn->prepare("
      UPDATE rep_repuestos
      SET sku=?,
          nombre=?,
          id_proveedor=?,
          id_categoria=?,
          id_unidad=?,
          id_almacen_default=?,
          stock_min=?,
          stock_max=?,
          imagen=?
      WHERE id=?
    ");
    if (!$stmt) {
      j(['ok'=>false,'msg'=>'Error en prepare: '.$cn->error]); break;
    }

    $stmt->bind_param(
      "ssiiiiiisi",
      $sku,
      $nombre,
      $id_prov,
      $id_cat,
      $id_um,
      $id_alm,
      $stockMin,
      $stockMax,
      $nombreImagen,
      $id
    );
    $ok = $stmt->execute();
    j(['ok'=>$ok, 'msg'=>$ok?'Repuesto actualizado correctamente':'No se pudo actualizar el repuesto']);
  break;

  /* ==========================================================
   * ELIMINAR REPUESTO (SI NO TIENE MOVIMIENTOS)
   * ========================================================== */
  case 'eliminar':
    $id = (int)($_POST['id'] ?? 0);
    if ($id<=0){ j(['ok'=>false,'msg'=>'ID inválido']); break; }

    // Verificar movimientos
    $stmt = $cn->prepare("SELECT COUNT(*) AS c FROM rep_movimientos WHERE id_repuesto=?");
    $stmt->bind_param("i", $id);
    $stmt->execute();
    $res = $stmt->get_result();
    $row = $res ? $res->fetch_assoc() : ['c'=>0];

    if((int)$row['c'] > 0){
      j(['ok'=>false,'msg'=>'No se puede eliminar: el repuesto tiene movimientos registrados']);
      break;
    }

    // Obtener imagen para borrarla físicamente (opcional)
    $stmtImg = $cn->prepare("SELECT imagen FROM rep_repuestos WHERE id=?");
    $stmtImg->bind_param("i", $id);
    $stmtImg->execute();
    $resImg = $stmtImg->get_result();
    $rowImg = $resImg ? $resImg->fetch_assoc() : null;
    $nombreImagen = $rowImg['imagen'] ?? '';

    $stmtDel = $cn->prepare("DELETE FROM rep_repuestos WHERE id=?");
    $stmtDel->bind_param("i", $id);
    $ok = $stmtDel->execute();

    if ($ok && $nombreImagen) {
      $carpeta = __DIR__ . '/../../Modelo/Archivos_Media/Repuestos/';
      $ruta    = $carpeta . $nombreImagen;
      if (is_file($ruta)) {
        @unlink($ruta);
      }
    }

    j(['ok'=>$ok,'msg'=>$ok?'Repuesto eliminado correctamente':'No se pudo eliminar el repuesto']);
  break;

  /* ==========================================================
   * KARDEX / MOVIMIENTOS POR REPUESTO
   * ========================================================== */
  case 'kardex':
    $id_rep = (int)($_GET['id_repuesto'] ?? 0);
    if ($id_rep<=0){ j(['ok'=>false,'msg'=>'ID repuesto inválido']); break; }

    $stmt = $cn->prepare("
      SELECT 
        m.id,
        m.id_repuesto,
        m.id_almacen,
        m.tipo,
        m.cantidad,
        m.costo_unitario,
        m.ref_tipo,
        m.ref_id,
        m.observacion,
        m.creado_por,
        m.creado_fecha
      FROM rep_movimientos m
      WHERE m.id_repuesto=?
      ORDER BY m.creado_fecha DESC, m.id DESC
    ");
    $stmt->bind_param("i", $id_rep);
    $stmt->execute();
    $res  = $stmt->get_result();
    $rows = $res ? $res->fetch_all(MYSQLI_ASSOC) : [];
    j(['ok'=>true,'data'=>$rows]);
  break;

  /* ==========================================================
   * BUSCAR REPUESTOS (SELECT2)
   * ========================================================== */
  case 'buscar_repuestos':
    $q   = trim($_GET['q'] ?? '');
    $sql = "SELECT id, CONCAT(sku,' - ',nombre) AS text FROM rep_repuestos WHERE 1=1 ";
    if ($q !== '') {
      $qLike = '%'.$cn->real_escape_string($q).'%';
      $sql  .= " AND (sku LIKE '$qLike' OR nombre LIKE '$qLike') ";
    }
    $sql .= " ORDER BY nombre LIMIT 50";
    $res  = $cn->query($sql);
    $rows = $res ? $res->fetch_all(MYSQLI_ASSOC) : [];
    j(['results'=>$rows]);
  break;

  /* ==========================================================
   * LISTAR ALMACENES (PARA SELECT2/FILTROS)
   * ========================================================== */
  case 'listar_almacenes':
    $res  = $cn->query("SELECT id, nombre AS text FROM rep_almacenes ORDER BY nombre");
    $rows = $res ? $res->fetch_all(MYSQLI_ASSOC) : [];
    j(['results'=>$rows]);
  break;

  /* ==========================================================
   * CREAR CATÁLOGOS AL VUELO
   * ========================================================== */
  case 'crear_categoria':
    $nom = trim($_POST['nombre'] ?? '');
    $des = trim($_POST['descripcion'] ?? '');
    if ($nom === ''){ j(['ok'=>false,'msg'=>'Nombre requerido']); break; }

    $stmt = $cn->prepare("INSERT INTO rep_categorias(nombre, descripcion) VALUES (?,?)");
    $stmt->bind_param("ss", $nom, $des);
    $ok = $stmt->execute();
    j([
      'ok' => $ok,
      'id' => $ok ? $cn->insert_id : 0,
      'msg'=> $ok ? 'Categoría creada correctamente' : 'No se pudo crear la categoría'
    ]);
  break;

  case 'crear_unidad':
    $nom = trim($_POST['nombre'] ?? '');
    $abr = trim($_POST['abreviatura'] ?? '');
    if ($nom==='' || $abr===''){
      j(['ok'=>false,'msg'=>'Nombre y abreviatura requeridos']);
      break;
    }
    $stmt = $cn->prepare("INSERT INTO rep_unidades(nombre, abreviatura) VALUES (?,?)");
    $stmt->bind_param("ss", $nom, $abr);
    $ok = $stmt->execute();
    j([
      'ok' => $ok,
      'id' => $ok ? $cn->insert_id : 0,
      'msg'=> $ok ? 'Unidad creada correctamente' : 'No se pudo crear la unidad'
    ]);
  break;

  case 'crear_almacen':
    $nom = trim($_POST['nombre'] ?? '');
    $ubi = trim($_POST['ubicacion'] ?? '');
    if ($nom===''){ j(['ok'=>false,'msg'=>'Nombre requerido']); break; }

    $stmt = $cn->prepare("INSERT INTO rep_almacenes(nombre, ubicacion) VALUES (?,?)");
    $stmt->bind_param("ss", $nom, $ubi);
    $ok = $stmt->execute();
    j([
      'ok' => $ok,
      'id' => $ok ? $cn->insert_id : 0,
      'msg'=> $ok ? 'Almacén creado correctamente' : 'No se pudo crear el almacén'
    ]);
  break;

  /* ===== CREAR PROVEEDOR AL VUELO ===== */
  case 'crear_proveedor':
    $nom = trim($_POST['nombre'] ?? '');
    $ruc = trim($_POST['ruc'] ?? '');
    $tel = trim($_POST['telefono'] ?? '');

    if ($nom===''){ j(['ok'=>false,'msg'=>'Nombre requerido']); break; }

    $stmt = $cn->prepare("INSERT INTO rep_proveedor(nombre, ruc, telefono) VALUES (?,?,?)");
    $stmt->bind_param("sss", $nom, $ruc, $tel);
    $ok = $stmt->execute();
    j([
      'ok' => $ok,
      'id' => $ok ? $cn->insert_id : 0,
      'msg'=> $ok ? 'Proveedor creado correctamente' : 'No se pudo crear el proveedor'
    ]);
  break;

  /* ========================================================== */
  default:
    j(['ok'=>false,'msg'=>'Acción no reconocida']);
}

$cn->close();
