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

require_once "../Utilidades/Conexion_BD.php";
require_once "../Utilidades/Auditoria.php";

/* --------------------------- Validaciones básicas --------------------------- */
if (!isset($_SESSION['usuario'])) {
  echo json_encode(['ok' => false, 'success' => false, 'message' => 'Sesión expirada.']);
  exit;
}

/** Valida fechas YYYY-MM-DD */
function validarFechaISO(?string $s): bool {
  if (!$s) return false;
  if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $s)) return false;
  [$y,$m,$d] = explode('-', $s);
  return checkdate((int)$m,(int)$d,(int)$y);
}

/* Acepta id o vehiculo_id desde el frontend */
$idVeh        = isset($_POST['vehiculo_id']) ? (int)$_POST['vehiculo_id'] : (int)($_POST['id'] ?? 0);
$nuevoEstado  = mb_strtolower(trim((string)($_POST['estado'] ?? '')), 'UTF-8'); // ← normalizado
$motivo       = isset($_POST['motivo']) ? trim((string)$_POST['motivo']) : null;
$fechaCambio  = $_POST['fecha_cambio']  ?? null; // cuando sale de ACTIVO
$fechaRegreso = $_POST['fecha_regreso'] ?? null; // cuando vuelve a ACTIVO

if ($idVeh <= 0 || $nuevoEstado === '') {
  echo json_encode(['ok'=>false,'success'=>false,'message'=>'Parámetros incompletos.']);
  exit;
}

/* Estados permitidos (clave = valor en BD) */
$estadosPermitidos = [
  'activo'         => 'Operativo',
  'no_operativo'   => 'No Operativo',
  'mantenimiento'  => 'Mantenimiento',
  'desincorporado' => 'Desincorporado',
];

if (!array_key_exists($nuevoEstado, $estadosPermitidos)) {
  echo json_encode(['ok'=>false,'success'=>false,'message'=>'Estado inválido.']);
  exit;
}

/* Motivo obligatorio cuando NO es ACTIVO */
if ($nuevoEstado !== 'activo' && ($motivo === null || $motivo === '')) {
  echo json_encode(['ok'=>false,'success'=>false,'message'=>'El motivo es obligatorio para este cambio de estado.']);
  exit;
}

/* Fecha requerida según el estado */
$fechaEvento = ($nuevoEstado === 'activo') ? $fechaRegreso : $fechaCambio;
$nombreCampo = ($nuevoEstado === 'activo') ? 'fecha_regreso' : 'fecha_cambio';
if (!$fechaEvento || !validarFechaISO($fechaEvento)) {
  echo json_encode(['ok'=>false,'success'=>false,'message'=>"Fecha inválida o faltante ($nombreCampo)."]);
  exit;
}

/* Sanitizar motivo y longitud */
if ($motivo !== null) {
  $motivo = mb_substr($motivo, 0, 255, 'UTF-8');
}

/* ------------------------------ Operación BD ------------------------------- */
try {
  $conn = new Conexion_BD();
  $db   = $conn->getConnection();

  $usuarioId = (int)($_SESSION['id_usuario'] ?? 0);
  $usuarioNm = $_SESSION['nombre'] ?? ($_SESSION['usuario'] ?? 'sistema');
  $rol       = $_SESSION['rol'] ?? '';

  $db->begin_transaction();

  // 1) Bloquear y leer estado actual
  $sql  = "SELECT estado, fecha_estado_desde FROM vehiculos WHERE id = ? FOR UPDATE";
  $stmt = $db->prepare($sql);
  if (!$stmt) throw new Exception("Error prepare SELECT: ".$db->error);
  $stmt->bind_param("i", $idVeh);
  $stmt->execute();
  $stmt->bind_result($estadoActual, $fechaDesdeActual);
  if (!$stmt->fetch()) {
    $stmt->close();
    throw new Exception("Vehículo no encontrado (ID $idVeh).");
  }
  $stmt->close();

  // Validación de coherencia de fechas al volver a ACTIVO
  if ($nuevoEstado === 'activo' && $fechaDesdeActual && $fechaEvento < $fechaDesdeActual) {
    throw new Exception("La fecha de regreso ($fechaEvento) no puede ser menor que la fecha desde la que dejó de estar activo ($fechaDesdeActual).");
  }

  // Si pasa a ACTIVO, limpiar motivo server-side (NULL) aunque el front no lo envíe vacío
  $motivoParaGuardar = ($nuevoEstado === 'activo') ? null : $motivo;

  // 2) Actualizar cabecera del vehículo (incluye fecha_estado_desde)
  if ($nuevoEstado === 'activo') {
    $sql  = "UPDATE vehiculos SET estado = 'activo', motivo_estado = NULL, fecha_estado_desde = ? WHERE id = ?";
    $stmt = $db->prepare($sql);
    if (!$stmt) throw new Exception("Error prepare UPDATE vehiculos (activo): ".$db->error);
    $stmt->bind_param("si", $fechaEvento, $idVeh);
  } else {
    $sql  = "UPDATE vehiculos SET estado = ?, motivo_estado = ?, fecha_estado_desde = ? WHERE id = ?";
    $stmt = $db->prepare($sql);
    if (!$stmt) throw new Exception("Error prepare UPDATE vehiculos: ".$db->error);
    $stmt->bind_param("sssi", $nuevoEstado, $motivoParaGuardar, $fechaEvento, $idVeh);
  }
  if (!$stmt->execute()) throw new Exception("Error ejecutando UPDATE vehiculos.");
  $stmt->close();

  // 3) Cerrar cualquier periodo abierto en historial
  $sql  = "UPDATE vehiculo_estado_historial
           SET fecha_fin = ?
           WHERE vehiculo_id = ? AND fecha_fin IS NULL";
  $stmt = $db->prepare($sql);
  if (!$stmt) throw new Exception("Error prepare UPDATE historial(fin): ".$db->error);
  $stmt->bind_param("si", $fechaEvento, $idVeh);
  if (!$stmt->execute()) throw new Exception("Error ejecutando UPDATE historial(fin).");
  $stmt->close();

  // 4) Abrir nuevo periodo con el estado actual
  $sql  = "INSERT INTO vehiculo_estado_historial
           (vehiculo_id, estado, fecha_inicio, fecha_fin, motivo, usuario_id)
           VALUES (?,?,?,?,?,?)";
  $stmt = $db->prepare($sql);
  if (!$stmt) throw new Exception("Error prepare INSERT historial: ".$db->error);
  $fin = null;
  $stmt->bind_param("issssi", $idVeh, $nuevoEstado, $fechaEvento, $fin, $motivoParaGuardar, $usuarioId);
  if (!$stmt->execute()) throw new Exception("Error ejecutando INSERT historial.");
  $stmt->close();

  // 5) Auditoría
  $descripcion = "Se cambió el estado del vehículo ID $idVeh a ".$estadosPermitidos[$nuevoEstado]." (fecha: $fechaEvento)";
  $observacion = $motivoParaGuardar ? "Motivo: $motivoParaGuardar" : "";
  registrarAuditoria(
    'vehiculos',
    'cambiar_estado',
    $descripcion,
    $usuarioId,
    $usuarioNm,
    'vehiculos',
    $idVeh,
    $rol,
    $observacion
  );

  $db->commit();
  $conn->closeConnection();

  echo json_encode([
    'ok'      => true,
    'success' => true,
    'message' => 'Estado del vehículo actualizado correctamente.',
    'msg'     => 'Estado del vehículo actualizado correctamente.',
    'fecha'   => $fechaEvento,
    'estado'  => $nuevoEstado,
  ]);
} catch (Throwable $e) {
  if (isset($db)) $db->rollback();
  if (isset($conn)) $conn->closeConnection();
  echo json_encode([
    'ok'      => false,
    'success' => false,
    'message' => 'Error al cambiar estado: '.$e->getMessage(),
    'msg'     => 'Error al cambiar estado: '.$e->getMessage(),
  ]);
}
