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

import type { DevicePluginConnectionProps } from "@mission-core/plugin-sdk";
import type {
  AcquisitionState,
  OperatorPresenceConfirmation,
  XgridsAcquisition,
} from "../api";
import {
  isSoftwareCommandedAcquisition,
  shouldRenderSpatialControls,
} from "../lifecycle";
import {
  deviceTelemetry,
  formatNumber,
  spatialActionFailure,
} from "../presentation";
import { useXgridsK1Controller } from "../runtimeContext";

interface PhasePresentation {
  label: string;
  detail: string;
  busy: boolean;
}

const PHYSICAL_ACCEPTANCE = {
  operator_present: true,
  owner_controlled_device: true,
  lixelgo_closed: true,
  battery_storage_confirmed: true,
  expected_physical_state_confirmed: true,
} satisfies OperatorPresenceConfirmation;

function phasePresentation(
  acquisition: XgridsAcquisition,
  softwareCommanded: boolean,
): PhasePresentation {
  const presentations: Record<AcquisitionState, PhasePresentation> = {
    preparing: {
      label: "Подготовка локального приёма",
      detail: "Проверяем контур и создаём сессию записи.",
      busy: true,
    },
    prepared: {
      label: "Приём подготовлен",
      detail: softwareCommanded
        ? "Можно инициировать работу устройства из Mission Core."
        : "Программная команда K1 недоступна в текущем профиле.",
      busy: false,
    },
    awaiting_external_start: {
      label: "Ожидание запуска на устройстве",
      detail: "Запустите сканирование физической кнопкой K1.",
      busy: true,
    },
    starting: {
      label: softwareCommanded
        ? "Калибровка оборудования"
        : "Подготовка локального приёмника",
      detail: softwareCommanded
        ? "Статическая инициализация после запуска — не перемещайте устройство."
        : "Mission Core запускает запись до физического старта K1.",
      busy: true,
    },
    acquiring: {
      label: softwareCommanded ? "K1 работает · запись активна" : "Локальная запись активна",
      detail: softwareCommanded
        ? "Состояние получено из профилированного контура управления K1."
        : "Mission Core принимает данные; физическое состояние K1 не управляется программно.",
      busy: false,
    },
    awaiting_external_stop: {
      label: softwareCommanded ? "K1 завершает и сохраняет" : "Ожидание остановки на устройстве",
      detail: softwareCommanded
        ? "STOP не повторяется. Mission Core завершит запись после READY от K1."
        : "Mission Core ждёт подтверждения физической остановки K1.",
      busy: true,
    },
    stopping: {
      label: softwareCommanded ? "Останавливаем K1 и запись" : "Останавливаем локальный приём",
      detail: softwareCommanded
        ? "Команда отправлена; ожидаем подтверждённое состояние устройства."
        : "Физическое состояние K1 остаётся неизвестным.",
      busy: true,
    },
    finalizing: {
      label: "Сохраняем локальную запись",
      detail: "Не закрывайте Mission Core до завершения финализации.",
      busy: true,
    },
    completed: { label: "Приём завершён", detail: "", busy: false },
    failed: { label: "Ошибка приёма", detail: "", busy: false },
    aborted: { label: "Приём прерван", detail: "", busy: false },
    interrupted: { label: "Приём прерван", detail: "", busy: false },
  };
  return presentations[acquisition.state];
}

function formatDuration(seconds: number): string {
  const wholeSeconds = Math.max(0, Math.floor(seconds));
  const hours = Math.floor(wholeSeconds / 3_600);
  const minutes = Math.floor((wholeSeconds % 3_600) / 60);
  const remainder = wholeSeconds % 60;
  return hours > 0
    ? `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}:${String(remainder).padStart(2, "0")}`
    : `${String(minutes).padStart(2, "0")}:${String(remainder).padStart(2, "0")}`;
}

export function K1SpatialControls(_props: DevicePluginConnectionProps) {
  const controller = useXgridsK1Controller();
  const { state, pendingAction, stop } = controller;
  const acquisition = state?.acquisition;
  const cleanupPending = acquisition?.cleanup_pending === true;
  if (!acquisition || !shouldRenderSpatialControls(state)) {
    return null;
  }

  const softwareCommanded = isSoftwareCommandedAcquisition(state);
  const phase = phasePresentation(acquisition, softwareCommanded);
  const telemetry = deviceTelemetry(state.metrics);
  const stopping = ["awaiting_external_stop", "stopping", "finalizing"].includes(
    acquisition.state,
  );
  const stopDisabled = pendingAction !== null || stopping;
  const controlFailure =
    state.application_control_session?.state === "failed"
      ? state.application_control_session.failure?.message ||
        "Канонический диалог остановлен; автоматический повтор запрещён."
      : null;
  const actionFailure = spatialActionFailure(
    controller.error ??
      controlFailure ??
      (cleanupPending
        ? "Локальный поток или архив ещё не завершён. Повторите остановку."
        : null),
  );

  return (
    <section
      className="xgrids-k1-spatial-controls"
      aria-label="Управление сессией XGRIDS K1"
      data-busy={phase.busy ? "true" : undefined}
    >
      <div className="xgrids-k1-spatial-controls__phase">
        {phase.busy ? <span className="xgrids-k1-spatial-controls__spinner" aria-hidden="true" /> : null}
        <span>
          <strong>{phase.label}</strong>
          <small>{phase.detail}</small>
        </span>
      </div>
      <div className="xgrids-k1-spatial-controls__telemetry" aria-label="Телеметрия маршрута K1">
        {telemetry.elapsedSeconds !== null ? (
          <span><small>Время сканирования</small><strong>{formatDuration(telemetry.elapsedSeconds)}</strong></span>
        ) : null}
        {telemetry.routeDistanceMeters !== null ? (
          <span><small>Маршрут устройства</small><strong>{formatNumber(telemetry.routeDistanceMeters, 2)} м</strong></span>
        ) : null}
        {telemetry.speedMetersPerSecond !== null ? (
          <span><small>Скорость</small><strong>{formatNumber(telemetry.speedMetersPerSecond, 2)} м/с</strong></span>
        ) : null}
      </div>
      {actionFailure ? (
        <div className="xgrids-k1-spatial-controls__error" role="alert">
          <strong>{actionFailure.title}</strong>
          <small>{actionFailure.detail}</small>
        </div>
      ) : null}
      <Button
        size="compact"
        variant="secondary"
        disabled={stopDisabled}
        onClick={() => void stop(softwareCommanded ? PHYSICAL_ACCEPTANCE : undefined)}
      >
        {pendingAction === "stop"
          ? softwareCommanded ? "Останавливаем устройство…" : "Останавливаем приём…"
          : stopping
            ? acquisition.state === "finalizing" ? "Сохраняем запись…" : "Остановка выполняется…"
            : actionFailure
              ? "Повторить остановку"
              : softwareCommanded ? "Остановить устройство и запись" : "Остановить локальный приём"}
      </Button>
    </section>
  );
}
