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

if (!isset($_SESSION['usuario'])) {
  echo json_encode(['ok'=>false,'success'=>false,'message'=>'Sesión expirada. Debe iniciar sesión nuevamente.']);
  exit;
}

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

/* ---------- Helpers ---------- */
function validarFechaISO($s) {
  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);
}

try {
  // Acepta id o galonera_id
  $idGalonera = isset($_POST['galonera_id']) ? (int)$_POST['galonera_id'] : (int)($_POST['id'] ?? 0);
  $nuevoEstado = strtolower(trim($_POST['estado'] ?? ''));
  $motivo      = isset($_POST['motivo']) ? trim($_POST['motivo']) : null;
  $fCambio     = $_POST['fecha_cambio']  ?? null;  // cuando sale de ACTIVO
  $fRegreso    = $_POST['fecha_regreso'] ?? null;  // cuando vuelve a ACTIVO

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

  // Estados válidos para galoneras
  $estadosValidos = ['activo','no_operativo','mantenimiento','desincorporado'];
  if (!in_array($nuevoEstado, $estadosValidos, true)) {
    echo json_encode(['ok'=>false,'success'=>false,'message'=>'Estado inválido.']);
    exit;
  }

  // La fecha requerida depende del estado
  $fechaEvento = ($nuevoEstado === 'activo') ? $fRegreso : $fCambio;
  if (!$fechaEvento || !validarFechaISO($fechaEvento)) {
    $et = ($nuevoEstado === 'activo') ? 'fecha_regreso' : 'fecha_cambio';
    echo json_encode(['ok'=>false,'success'=>false,'message'=>"Fecha inválida o faltante ($et)."]);
    exit;
  }

  // Motivo: si quieres igualar al comportamiento de choferes (solo obligatorio al desincorporar) deja este if.
  // Si prefieres exigir motivo para TODO estado no ACTIVO, cambia la condición a ($nuevoEstado !== 'activo').
  if ($nuevoEstado === 'desincorporado' && ($motivo === null || $motivo === '')) {
    echo json_encode(['ok'=>false,'success'=>false,'message'=>'Motivo obligatorio para desincorporar.']);
    exit;
  }

  $conn      = new Conexion_BD();
  $db        = $conn->getConnection();
  $usuarioId = isset($_SESSION['id_usuario']) ? (int)$_SESSION['id_usuario'] : null;
  $usuarioNm = $_SESSION['nombre'] ?? ($_SESSION['usuario'] ?? 'sistema');
  $rol       = $_SESSION['rol'] ?? '';

  $db->begin_transaction();

  /* 1) Leer estado actual y bloquear fila */
  $sql = "SELECT estado, fecha_estado_desde FROM galoneras WHERE id = ? FOR UPDATE";
  $stmt = $db->prepare($sql);
  if (!$stmt) throw new Exception("Error prepare SELECT galoneras: ".$db->error);
  $stmt->bind_param("i", $idGalonera);
  $stmt->execute();
  $stmt->bind_result($estadoActual, $fechaDesdeActual);
  if (!$stmt->fetch()) {
    $stmt->close();
    throw new Exception("Galonera no encontrada (ID $idGalonera).");
  }
  $stmt->close();

  /* 2) Gestionar historial correctamente (sin cerrar antes de decidir) */
  // Recuperar el último período ABIERTO (si existe)
  $openId = null; $openEstado = null;
  $sql = "SELECT id, estado FROM galonera_estado_historial
          WHERE galonera_id = ? AND fecha_fin IS NULL
          ORDER BY id DESC LIMIT 1";
  if ($stmt = $db->prepare($sql)) {
    $stmt->bind_param("i", $idGalonera);
    $stmt->execute();
    $stmt->bind_result($openId, $openEstado);
    $stmt->fetch();
    $stmt->close();
  }

  if ($openId !== null) {
    if ($openEstado === $nuevoEstado) {
      // Mismo estado -> ajustar inicio y motivo del período abierto
      $sql = "UPDATE galonera_estado_historial
              SET fecha_inicio = ?, motivo = ?, usuario_id = ?
              WHERE id = ?";
      $stmt = $db->prepare($sql);
      if (!$stmt) throw new Exception("Error prepare UPDATE historial (ajustar mismo estado): ".$db->error);
      $stmt->bind_param("ssii", $fechaEvento, $motivo, $usuarioId, $openId);
      if (!$stmt->execute()) throw new Exception("Error ejecutando UPDATE historial (ajustar mismo estado).");
      $stmt->close();
    } else {
      // Estado CAMBIA -> cerrar período abierto con fechaEvento e insertar nuevo abierto
      $sql = "UPDATE galonera_estado_historial SET fecha_fin = ?, usuario_id = ? WHERE id = ?";
      $stmt = $db->prepare($sql);
      if (!$stmt) throw new Exception("Error prepare UPDATE historial (cerrar): ".$db->error);
      $stmt->bind_param("sii", $fechaEvento, $usuarioId, $openId);
      if (!$stmt->execute()) throw new Exception("Error ejecutando UPDATE historial (cerrar).");
      $stmt->close();

      $sql = "INSERT INTO galonera_estado_historial
              (galonera_id, estado, fecha_inicio, fecha_fin, motivo, usuario_id)
              VALUES (?,?,?,?,?,?)";
      $stmt = $db->prepare($sql);
      if (!$stmt) throw new Exception("Error prepare INSERT historial (nuevo estado): ".$db->error);
      $null = null;
      $stmt->bind_param("issssi", $idGalonera, $nuevoEstado, $fechaEvento, $null, $motivo, $usuarioId);
      if (!$stmt->execute()) throw new Exception("Error ejecutando INSERT historial (nuevo estado).");
      $stmt->close();
    }
  } else {
    // No hay abierto -> crear uno nuevo con el nuevo estado
    $sql = "INSERT INTO galonera_estado_historial
            (galonera_id, estado, fecha_inicio, fecha_fin, motivo, usuario_id)
            VALUES (?,?,?,?,?,?)";
    $stmt = $db->prepare($sql);
    if (!$stmt) throw new Exception("Error prepare INSERT historial (sin abierto): ".$db->error);
    $null = null;
    $stmt->bind_param("issssi", $idGalonera, $nuevoEstado, $fechaEvento, $null, $motivo, $usuarioId);
    if (!$stmt->execute()) throw new Exception("Error ejecutando INSERT historial (sin abierto).");
    $stmt->close();
  }

  /* 3) Actualizar galoneras (estado, motivo, fecha_estado_desde) */
  $sql = "UPDATE galoneras SET estado = ?, motivo_estado = ?, fecha_estado_desde = ? WHERE id = ?";
  $stmt = $db->prepare($sql);
  if (!$stmt) throw new Exception("Error prepare UPDATE galoneras: ".$db->error);
  $stmt->bind_param("sssi", $nuevoEstado, $motivo, $fechaEvento, $idGalonera);
  if (!$stmt->execute()) throw new Exception("Error ejecutando UPDATE galoneras.");
  $stmt->close();

  /* 4) Auditoría */
  $descripcion = "Se cambió el estado de la galonera ID $idGalonera a $nuevoEstado (fecha: $fechaEvento)";
  $observacion = trim(($motivo ? "Motivo: $motivo" : ""));
  registrarAuditoria(
    'galoneras',
    'cambiar_estado',
    $descripcion,
    $usuarioId ?? 0,
    $usuarioNm,
    'galoneras',
    $idGalonera,
    $rol,
    $observacion
  );

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

  echo json_encode([
    'ok'           => true,
    'success'      => true,
    'message'      => 'Estado actualizado correctamente.',
    'msg'          => 'Estado actualizado correctamente.',
    'fecha'        => $fechaEvento,
    'estado'       => $nuevoEstado,
    'fecha_desde'  => $fechaEvento
  ]);
} catch (Throwable $e) {
  if (isset($db)) { $db->rollback(); }
  if (isset($conn)) { $conn->closeConnection(); }

  echo json_encode([
    'ok'      => false,
    'success' => false,
    'message' => 'Error en el servidor: '.$e->getMessage(),
    'msg'     => 'Error en el servidor: '.$e->getMessage()
  ]);
}
