import type { RuntimePhase, SourceMode as RuntimeSourceMode } from "@mission-core/plugin-sdk";

import type {
  AcquisitionState,
  XgridsApplicationControlPhase,
  XgridsAcquisition,
  XgridsK1State,
  XgridsOperation,
} from "./api";

const TERMINAL_ACQUISITION_STATES = new Set<AcquisitionState>([
  "completed",
  "failed",
  "aborted",
  "interrupted",
]);

const FAILED_OPERATION_STATUSES = new Set([
  "failed",
  "cancelled",
  "timed_out",
  "interrupted",
]);

export type LiveStartPlan = "prepare" | "resume-prepared" | "already-running" | "blocked";
export type ControlSessionEntryPlan =
  | "open"
  | "continue"
  | "failed"
  | "duplicate-open";

export function controlSessionEntryPlan(
  phase: XgridsApplicationControlPhase,
  openedByCurrentOperatorAction: boolean,
  canOpen: boolean,
): ControlSessionEntryPlan {
  if (phase === "failed") {
    return !openedByCurrentOperatorAction && canOpen ? "open" : "failed";
  }
  if (["idle", "closed", "completed"].includes(phase)) {
    return openedByCurrentOperatorAction ? "duplicate-open" : "open";
  }
  return "continue";
}

export function isTerminalAcquisitionState(
  state: AcquisitionState | null | undefined,
): boolean {
  return state ? TERMINAL_ACQUISITION_STATES.has(state) : false;
}

export function shouldRenderSpatialControls(
  state: XgridsK1State | null | undefined,
): boolean {
  const acquisition = state?.acquisition;
  if (!acquisition || state?.source_mode === "replay") return false;
  return (
    !isTerminalAcquisitionState(acquisition.state) ||
    acquisition.cleanup_pending === true
  );
}

export function recoverableAcquisition(
  state: XgridsK1State | null | undefined,
): XgridsAcquisition | null {
  const acquisition = state?.acquisition;
  return acquisition && !isTerminalAcquisitionState(acquisition.state) ? acquisition : null;
}

export function isConfirmedLiveState(state: XgridsK1State | null | undefined): boolean {
  return state?.source_mode === "live" && state.acquisition?.state === "acquiring";
}

export function isSourceRuntimeBusy(state: XgridsK1State | null | undefined): boolean {
  return state?.source_mode === "live" || state?.source_mode === "replay";
}

export function isVendorWriteCapable(
  state: XgridsK1State | null | undefined,
): boolean {
  return (
    state?.compatibility?.vendor_writes_enabled === true &&
    state.compatibility.permitted_mode === "active-control"
  );
}

export function isSoftwareCommandedAcquisition(
  state: XgridsK1State | null | undefined,
): boolean {
  return isVendorWriteCapable(state) && state?.acquisition?.control_mode === "plugin-commanded";
}

export function confirmedRuntimeSourceMode(
  state: XgridsK1State | null | undefined,
): RuntimeSourceMode {
  if (state?.source_mode === "replay") return "replay";
  if (isConfirmedLiveState(state)) return "live";
  return "idle";
}

export function effectiveAcquisition(
  state: XgridsK1State | null | undefined,
): XgridsAcquisition | null {
  if (state?.source_mode === "replay") return null;
  return state?.acquisition ?? null;
}

export function liveStartPlan(state: XgridsK1State | null | undefined): LiveStartPlan {
  if (state?.source_mode === "replay") return "blocked";
  const acquisition = recoverableAcquisition(state);
  if (!acquisition) return state?.source_mode === "live" ? "blocked" : "prepare";
  if (acquisition.state === "prepared") return "resume-prepared";
  if (
    acquisition.state === "starting" ||
    acquisition.state === "awaiting_external_start" ||
    acquisition.state === "acquiring"
  ) {
    return "already-running";
  }
  return "blocked";
}

export function normalizeRuntimePhase(
  state: XgridsK1State | null | undefined,
): RuntimePhase {
  const phase = state?.phase;
  const acquisitionState = effectiveAcquisition(state)?.state;
  if (acquisitionState === "failed" || acquisitionState === "interrupted") return "error";
  if (acquisitionState === "awaiting_external_start" || acquisitionState === "starting") {
    return "starting";
  }
  if (acquisitionState === "acquiring") return "streaming";
  if (
    acquisitionState === "awaiting_external_stop" ||
    acquisitionState === "stopping" ||
    acquisitionState === "finalizing"
  ) {
    return "stopping";
  }
  if (acquisitionState === "prepared") return "connected";
  if (phase === "error") return "error";
  if (phase === "connected") {
    const controlPhase = state?.application_control_session?.state;
    return controlPhase && !["idle", "connecting", "closed", "completed", "failed"].includes(controlPhase)
      ? "connected"
      : "configuring";
  }
  if (phase === "starting_live") return "starting";
  if (phase === "live") return "streaming";
  if (phase === "replay") return "replaying";
  if (phase === "stopping") return "stopping";
  if (["scanning", "device_selected", "provisioning", "connecting"].includes(phase ?? "")) {
    return "configuring";
  }
  return "idle";
}

export function spatialSourceId(
  state: XgridsK1State | null | undefined,
  sourceUrl: string,
): string | null {
  if (!sourceUrl) return null;
  if (state?.source_mode === "replay") return `replay:${sourceUrl}`;
  return state?.acquisition?.acquisition_id ?? sourceUrl;
}

export function sourceStatusLabel(state: XgridsK1State | null | undefined): string {
  if (state?.source_mode === "replay") return "Повтор записи";
  if (isConfirmedLiveState(state)) return "Реальное время · данные подтверждены";
  if (state?.source_mode === "live") {
    if (state.acquisition?.state === "failed" || state.phase === "error") {
      return "Ошибка локального приёмника";
    }
    return "Ожидание реальных данных";
  }
  if (state?.acquisition?.state === "prepared") return "Приём подготовлен";
  return "Ожидание";
}

export function operationByIdempotencyKey(
  state: XgridsK1State | null | undefined,
  action: string,
  idempotencyKey: string | null | undefined,
): XgridsOperation | null {
  if (!idempotencyKey) return null;
  return (
    [...(state?.operations ?? [])]
      .reverse()
      .find(
        (operation) =>
          operation.action === action && operation.idempotency_key === idempotencyKey,
      ) ?? null
  );
}

export function operationNeedsReconciliation(
  operation: XgridsOperation | null | undefined,
): boolean {
  if (!operation || !FAILED_OPERATION_STATUSES.has(operation.status)) return false;
  return operation.error?.safe_to_retry !== true;
}

function defaultUuid(): string {
  const cryptoApi = globalThis.crypto;
  if (!cryptoApi) {
    throw new Error("Web Crypto недоступен; безопасный идентификатор операции не создан.");
  }
  if (typeof cryptoApi.randomUUID === "function") return cryptoApi.randomUUID();
  const bytes = new Uint8Array(16);
  cryptoApi.getRandomValues(bytes);
  bytes[6] = (bytes[6] & 0x0f) | 0x40;
  bytes[8] = (bytes[8] & 0x3f) | 0x80;
  const hex = [...bytes].map((value) => value.toString(16).padStart(2, "0"));
  return `${hex.slice(0, 4).join("")}-${hex.slice(4, 6).join("")}-${hex
    .slice(6, 8)
    .join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10).join("")}`;
}

export function provisioningIntentKey(
  current: string | null,
  createUuid: () => string = defaultUuid,
): string {
  return current ?? `network-provision:${createUuid()}`;
}
