import { clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';

// lib/cn.ts
function cn(...inputs) {
  return twMerge(clsx(inputs));
}

// lib/debug.ts
var DEBUG_ENABLED = typeof window !== "undefined" && (localStorage.getItem("debug") === "true" || process.env.NODE_ENV === "development");
function isDebugEnabled() {
  return DEBUG_ENABLED;
}
function debug(...args) {
  if (DEBUG_ENABLED) {
    console.log("[DEBUG]", ...args);
  }
}
function debugGroup(label) {
  if (DEBUG_ENABLED) {
    console.group(`[DEBUG] ${label}`);
  }
}
function debugGroupEnd() {
  if (DEBUG_ENABLED) {
    console.groupEnd();
  }
}
function debugWarn(...args) {
  if (DEBUG_ENABLED) {
    console.warn("[DEBUG]", ...args);
  }
}
function debugError(...args) {
  if (DEBUG_ENABLED) {
    console.error("[DEBUG]", ...args);
  }
}
function debugTable(data) {
  if (DEBUG_ENABLED) {
    console.table(data);
  }
}
function debugTime(label) {
  if (DEBUG_ENABLED) {
    console.time(`[DEBUG] ${label}`);
  }
}
function debugTimeEnd(label) {
  if (DEBUG_ENABLED) {
    console.timeEnd(`[DEBUG] ${label}`);
  }
}
function debugInput(inputType, data) {
  if (DEBUG_ENABLED) {
    console.log(`[DEBUG:INPUT] ${inputType}:`, data);
  }
}
function debugCollision(entityA, entityB, details) {
  if (DEBUG_ENABLED) {
    console.log(
      `[DEBUG:COLLISION] ${entityA.type || entityA.id} <-> ${entityB.type || entityB.id}`,
      details ?? ""
    );
  }
}
function debugPhysics(entityId, physics) {
  if (DEBUG_ENABLED) {
    console.log(`[DEBUG:PHYSICS] ${entityId}:`, physics);
  }
}
function debugGameState(stateName, value) {
  if (DEBUG_ENABLED) {
    console.log(`[DEBUG:GAME_STATE] ${stateName}:`, value);
  }
}

// lib/verificationRegistry.ts
var checks = /* @__PURE__ */ new Map();
var transitions = [];
var bridgeHealth = null;
var MAX_TRANSITIONS = 500;
var listeners = /* @__PURE__ */ new Set();
function notifyListeners() {
  listeners.forEach((l) => l());
  exposeOnWindow();
}
function registerCheck(id, label, status = "pending", details) {
  checks.set(id, { id, label, status, details, updatedAt: Date.now() });
  notifyListeners();
}
function updateCheck(id, status, details) {
  const check = checks.get(id);
  if (check) {
    check.status = status;
    if (details !== void 0) check.details = details;
    check.updatedAt = Date.now();
  } else {
    checks.set(id, { id, label: id, status, details, updatedAt: Date.now() });
  }
  notifyListeners();
}
function getAllChecks() {
  return Array.from(checks.values());
}
function recordTransition(trace) {
  const entry = {
    ...trace,
    id: `t-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
  };
  transitions.push(entry);
  if (transitions.length > MAX_TRANSITIONS) {
    transitions.shift();
  }
  if (entry.event === "INIT") {
    const hasFetch = entry.effects.some((e) => e.type === "fetch");
    const checkId = `init-fetch-${entry.traitName}`;
    if (hasFetch) {
      registerCheck(
        checkId,
        `INIT transition for "${entry.traitName}" has fetch effect`,
        "pass"
      );
    } else {
      const hasRenderUI = entry.effects.some((e) => e.type === "render-ui");
      if (hasRenderUI) {
        registerCheck(
          checkId,
          `INIT transition for "${entry.traitName}" missing fetch effect`,
          "fail",
          "Entity-bound render-ui without a fetch effect will show empty data"
        );
      }
    }
  }
  const failedEffects = entry.effects.filter((e) => e.status === "failed");
  if (failedEffects.length > 0) {
    registerCheck(
      `effects-${entry.id}`,
      `Effects failed in ${entry.traitName}: ${entry.from} -> ${entry.to}`,
      "fail",
      failedEffects.map((e) => `${e.type}: ${e.error}`).join("; ")
    );
  }
  notifyListeners();
}
function getTransitions() {
  return [...transitions];
}
function getTransitionsForTrait(traitName) {
  return transitions.filter((t) => t.traitName === traitName);
}
function updateBridgeHealth(health) {
  bridgeHealth = { ...health };
  const checkId = "server-bridge";
  if (health.connected) {
    registerCheck(checkId, "Server bridge connected", "pass");
  } else {
    registerCheck(
      checkId,
      "Server bridge disconnected",
      "fail",
      health.lastError || "Bridge is not connected"
    );
  }
  notifyListeners();
}
function getBridgeHealth() {
  return bridgeHealth ? { ...bridgeHealth } : null;
}
function getSummary() {
  const allChecks = getAllChecks();
  return {
    totalChecks: allChecks.length,
    passed: allChecks.filter((c) => c.status === "pass").length,
    failed: allChecks.filter((c) => c.status === "fail").length,
    warnings: allChecks.filter((c) => c.status === "warn").length,
    pending: allChecks.filter((c) => c.status === "pending").length
  };
}
function getSnapshot() {
  return {
    checks: getAllChecks(),
    transitions: getTransitions(),
    bridge: getBridgeHealth(),
    summary: getSummary()
  };
}
function subscribeToVerification(listener) {
  listeners.add(listener);
  return () => listeners.delete(listener);
}
function exposeOnWindow() {
  if (typeof window === "undefined") return;
  if (!window.__orbitalVerification) {
    window.__orbitalVerification = {
      getSnapshot,
      getChecks: getAllChecks,
      getTransitions,
      getBridge: getBridgeHealth,
      getSummary,
      waitForTransition
    };
  }
}
function waitForTransition(event, timeoutMs = 1e4) {
  return new Promise((resolve) => {
    const existing = transitions.find((t) => t.event === event);
    if (existing) {
      resolve(existing);
      return;
    }
    const timeout = setTimeout(() => {
      unsub();
      resolve(null);
    }, timeoutMs);
    const unsub = subscribeToVerification(() => {
      const found = transitions.find((t) => t.event === event);
      if (found) {
        clearTimeout(timeout);
        unsub();
        resolve(found);
      }
    });
  });
}
function bindEventBus(eventBus) {
  if (typeof window === "undefined") return;
  exposeOnWindow();
  if (window.__orbitalVerification) {
    window.__orbitalVerification.sendEvent = (event, payload) => {
      const prefixed = event.startsWith("UI:") ? event : `UI:${event}`;
      eventBus.emit(prefixed, payload);
    };
    const eventLog = [];
    window.__orbitalVerification.eventLog = eventLog;
    window.__orbitalVerification.clearEventLog = () => {
      eventLog.length = 0;
    };
    if (eventBus.onAny) {
      eventBus.onAny((event) => {
        if (eventLog.length < 200) {
          eventLog.push({
            type: event.type,
            payload: event.payload,
            timestamp: Date.now()
          });
        }
      });
    }
  }
}
function bindTraitStateGetter(getter) {
  if (typeof window === "undefined") return;
  exposeOnWindow();
  if (window.__orbitalVerification) {
    window.__orbitalVerification.getTraitState = getter;
  }
}
function bindCanvasCapture(captureFn) {
  if (typeof window === "undefined") return;
  exposeOnWindow();
  if (window.__orbitalVerification) {
    window.__orbitalVerification.captureFrame = captureFn;
  }
}
function updateAssetStatus(url, status) {
  if (typeof window === "undefined") return;
  exposeOnWindow();
  if (window.__orbitalVerification) {
    if (!window.__orbitalVerification.assetStatus) {
      window.__orbitalVerification.assetStatus = {};
    }
    window.__orbitalVerification.assetStatus[url] = status;
  }
}
function clearVerification() {
  checks.clear();
  transitions.length = 0;
  bridgeHealth = null;
  notifyListeners();
}
exposeOnWindow();

// lib/getNestedValue.ts
function getNestedValue(obj, path) {
  if (obj === null || obj === void 0 || !path) {
    return void 0;
  }
  if (!path.includes(".")) {
    return obj[path];
  }
  const parts = path.split(".");
  let value = obj;
  for (const part of parts) {
    if (value === null || value === void 0) {
      return void 0;
    }
    if (typeof value !== "object") {
      return void 0;
    }
    value = value[part];
  }
  return value;
}
function formatNestedFieldLabel(path) {
  const lastPart = path.includes(".") ? path.split(".").pop() : path;
  return lastPart.replace(/([A-Z])/g, " $1").replace(/^./, (str) => str.toUpperCase()).replace(/Id$/, "").trim();
}

export { bindCanvasCapture, bindEventBus, bindTraitStateGetter, clearVerification, cn, debug, debugCollision, debugError, debugGameState, debugGroup, debugGroupEnd, debugInput, debugPhysics, debugTable, debugTime, debugTimeEnd, debugWarn, formatNestedFieldLabel, getAllChecks, getBridgeHealth, getNestedValue, getSnapshot, getSummary, getTransitions, getTransitionsForTrait, isDebugEnabled, recordTransition, registerCheck, subscribeToVerification, updateAssetStatus, updateBridgeHealth, updateCheck, waitForTransition };
