import type { StatusTone } from "@nodedc/ui-react";

import type { BackendStatus } from "@mission-core/plugin-sdk";
import type { XgridsK1Metrics } from "./api";

const phaseLabels: Record<string, string> = {
  idle: "Ожидание",
  scanning: "Поиск Bluetooth",
  device_selected: "Устройство выбрано",
  provisioning: "Передача настроек Wi‑Fi",
  connecting: "Подключение",
  connected: "Сетевой адрес устройства получен",
  starting_live: "Запуск потока",
  live: "Поток в реальном времени",
  replay: "Повтор записи",
  stopping: "Остановка",
  error: "Ошибка",
};

export function phaseLabel(phase: string | null | undefined): string {
  if (!phase) return "Нет состояния";
  return phaseLabels[phase] ?? "Неизвестное состояние";
}

export function phaseTone(phase: string | null | undefined): StatusTone {
  if (!phase) return "neutral";
  if (phase === "error") return "danger";
  if (["live", "replay"].includes(phase)) return "success";
  if (phase === "connected") return "warning";
  if (["scanning", "provisioning", "connecting", "starting_live", "stopping"].includes(phase)) return "accent";
  return "neutral";
}

export function backendLabel(status: BackendStatus): string {
  return {
    unconfigured: "Модель не выбрана",
    checking: "Проверка контура",
    online: "Контур доступен",
    degraded: "Контур ограничен",
    offline: "Контур недоступен",
  }[status];
}

export function backendTone(status: BackendStatus): StatusTone {
  if (status === "online") return "success";
  if (status === "degraded" || status === "checking") return "warning";
  if (status === "unconfigured") return "neutral";
  return "danger";
}

export function eventStatusLabel(status: string): string {
  return {
    connecting: "подключение",
    open: "подключён",
    closed: "закрыт",
    error: "ошибка",
  }[status] ?? "неизвестно";
}

export function finiteMetric(value: number | null | undefined): number | null {
  return typeof value === "number" && Number.isFinite(value) ? value : null;
}

export function pipelineLatency(metrics: XgridsK1Metrics | undefined): number | null {
  if (!metrics) return null;
  const direct = finiteMetric(metrics.pipeline_ms ?? metrics.end_to_end_ms);
  if (direct !== null) return direct;
  const segments = [finiteMetric(metrics.mqtt_to_decode_ms), finiteMetric(metrics.publish_ms)]
    .filter((value): value is number => value !== null);
  return segments.length === 2 ? segments.reduce((total, value) => total + value, 0) : null;
}

function nonNegativeMetric(value: number | null | undefined): number | null {
  const finite = finiteMetric(value);
  return finite !== null && finite >= 0 ? finite : null;
}

export interface K1DeviceTelemetry {
  elapsedSeconds: number | null;
  routeDistanceMeters: number | null;
  speedMetersPerSecond: number | null;
}

export interface SpatialActionFailure {
  title: string;
  detail: string;
}

export function spatialActionFailure(
  error: string | null | undefined,
): SpatialActionFailure | null {
  const detail = error?.trim();
  return detail
    ? {
        title: "Действие K1 не выполнено",
        detail,
      }
    : null;
}

export function deviceTelemetry(
  metrics: XgridsK1Metrics | null | undefined,
): K1DeviceTelemetry {
  return {
    elapsedSeconds: nonNegativeMetric(
      metrics?.device_elapsed_seconds ?? metrics?.elapsed_seconds,
    ),
    routeDistanceMeters: nonNegativeMetric(
      metrics?.device_route_distance_meters ?? metrics?.route_distance_meters,
    ),
    speedMetersPerSecond: nonNegativeMetric(
      metrics?.device_speed_meters_per_second ??
        metrics?.device_speed_mps ??
        metrics?.speed_meters_per_second,
    ),
  };
}

export function formatNumber(value: number | null, digits = 1): string {
  if (value === null) return "—";
  return value.toLocaleString("ru-RU", {
    maximumFractionDigits: digits,
    minimumFractionDigits: digits,
  });
}

export function sourceModeLabel(mode: string | null | undefined): string {
  if (mode === "live") return "Реальное время";
  if (mode === "replay") return "Повтор записи";
  if (mode === "idle") return "Ожидание";
  return "Неизвестно";
}
