import { useEffect, useMemo, useRef, useState, type ReactNode } from "react";
import {
  Button,
  Checker,
  GlassSurface,
  Icon,
  Select,
  StatusBadge,
  TextField,
  type StatusTone,
} from "@nodedc/ui-react";

import type { BleDevice } from "../api";
import { profileSelectionForConnectionMode } from "../compatibility";
import {
  DEFAULT_CONNECTION_MODE,
  connectionModeOptions,
  type ConnectionMode,
} from "../configuration";
import { provisioningIntentKey } from "../lifecycle";
import { finiteMetric } from "../presentation";
import type { XgridsK1Controller } from "../runtimeContext";

const connectionCopy: Record<ConnectionMode, {
  stepTitle: string;
  ssidLabel?: string;
  ssidPlaceholder?: string;
  buttonLabel: string;
  safetyNote: string;
}> = {
  bridge: {
    stepTitle: "Передайте настройки общей сети",
    ssidLabel: "Название общей сети Wi‑Fi",
    ssidPlaceholder: "Сеть локального контура",
    buttonLabel: "Подключить K1 к общей сети",
    safetyNote: "K1 получит реквизиты существующей сети одним рассмотренным BLE-запросом без автоматического повтора.",
  },
  "quick-connect": {
    stepTitle: "Включите точку доступа K1 и подключитесь к ней",
    buttonLabel: "Включить точку K1 и подключиться",
    safetyNote: "Mission Core сначала проверит локальный device-scoped профиль выбранного K1. Если профиль отсутствует, операция остановится до BLE-записи. После preflight Mission Core отправит один рассмотренный AP-enable кадр и найдёт точный SSID выбранного устройства.",
  },
  "direct-connect": {
    stepTitle: "Подключите K1 к хотспоту контроллера",
    ssidLabel: "Название хотспота контроллера",
    ssidPlaceholder: "SSID управляющего устройства",
    buttonLabel: "Подключить K1 к хотспоту",
    safetyNote: "Хотспот должен быть уже включён, а управляющее устройство — иметь к нему маршрут. K1 получит его реквизиты одним рассмотренным BLE-запросом.",
  },
};

function WizardStep({
  number,
  title,
  status,
  tone = "neutral",
  children,
}: {
  number: string;
  title: string;
  status: string;
  tone?: StatusTone;
  children: ReactNode;
}) {
  return (
    <section className="wizard-step">
      <div className="wizard-step__rail" aria-hidden="true"><span>{number}</span></div>
      <div className="wizard-step__content">
        <header><h3>{title}</h3><StatusBadge tone={tone}>{status}</StatusBadge></header>
        {children}
      </div>
    </section>
  );
}

function DeviceRow({ device, selected, onSelect }: {
  device: BleDevice;
  selected: boolean;
  onSelect: () => void;
}) {
  return (
    <div
      className="device-row"
      data-compatible={device.likely_k1 ? "true" : undefined}
      data-selected={selected ? "true" : undefined}
    >
      <div className="device-row__identity">
        <span className="device-row__signal" aria-hidden="true" />
        <div>
          <span className="device-row__name">
            <strong>{device.name?.trim() || "Устройство без имени"}</strong>
            {device.likely_k1 ? <small>Кандидат по имени; профиль не подтверждён</small> : null}
          </span>
          <code>{device.device_id}</code>
        </div>
      </div>
      <div className="device-row__action">
        <span>{finiteMetric(device.rssi) === null ? "RSSI —" : `${device.rssi} дБм`}</span>
        <Button
          size="compact"
          variant={selected ? "primary" : "secondary"}
          disabled={device.connectable === false}
          onClick={onSelect}
        >
          {selected ? "Выбрано" : "Выбрать"}
        </Button>
      </div>
    </div>
  );
}

export function K1ProvisioningPipeline({
  controller,
  phaseLabel,
  phaseTone,
}: {
  controller: XgridsK1Controller;
  phaseLabel: string;
  phaseTone: StatusTone;
}) {
  const { state, pendingAction, scan, connect } = controller;
  const [powerConfirmed, setPowerConfirmed] = useState(false);
  const [selectedDeviceId, setSelectedDeviceId] = useState("");
  const [ssid, setSsid] = useState("");
  const [password, setPassword] = useState("");
  const [connectionMode, setConnectionMode] = useState<ConnectionMode>(
    DEFAULT_CONNECTION_MODE,
  );
  const provisioningIntentRef = useRef<string | null>(null);
  const devices = state?.devices ?? [];
  const isBusy = pendingAction !== null;
  const credentialsReady = connectionMode === "quick-connect"
    || (ssid.trim().length > 0 && password.length > 0);
  const canConnect = powerConfirmed && selectedDeviceId.length > 0 && credentialsReady && !isBusy;
  const modeCopy = connectionCopy[connectionMode];
  const selectedModeConnected = Boolean(
    state?.k1_ip && state.connection_mode === connectionMode,
  );

  useEffect(() => {
    if (state?.selected_device_id) {
      if (state.selected_device_id !== selectedDeviceId) {
        provisioningIntentRef.current = null;
      }
      setSelectedDeviceId(state.selected_device_id);
      return;
    }
    if (selectedDeviceId && state?.devices && !state.devices.some((device) => device.device_id === selectedDeviceId)) {
      setSelectedDeviceId("");
    }
  }, [selectedDeviceId, state?.devices, state?.selected_device_id]);

  useEffect(() => {
    if (state?.connection_mode) {
      setConnectionMode(state.connection_mode);
    }
  }, [state?.connection_mode]);

  const deviceSummary = useMemo(
    () => devices.find((device) => device.device_id === selectedDeviceId),
    [devices, selectedDeviceId],
  );

  const resetProvisioningIntent = () => {
    provisioningIntentRef.current = null;
  };

  const submitConnect = async () => {
    if (!canConnect) return;
    const idempotencyKey = provisioningIntentKey(provisioningIntentRef.current);
    provisioningIntentRef.current = idempotencyKey;
    const networkCredentials = connectionMode === "quick-connect"
      ? {}
      : { ssid: ssid.trim(), password };
    const succeeded = await connect({
      device_id: selectedDeviceId,
      ...networkCredentials,
      connection_mode: connectionMode,
      compatibility_attestation: profileSelectionForConnectionMode(connectionMode),
      idempotency_key: idempotencyKey,
    });
    if (succeeded) {
      provisioningIntentRef.current = null;
      setPassword("");
    } else if (connectionMode === "quick-connect") {
      // The backend has already persisted and reconciled the failed bounded
      // attempt. A later click is a new explicit Quick Connect intent, not an
      // automatic replay of the consumed operation key.
      provisioningIntentRef.current = null;
    }
  };

  return (
    <GlassSurface className="connection-panel" padding="lg">
      <header className="panel-heading">
        <div><span className="section-eyebrow">ПОДКЛЮЧЕНИЕ · ШАГИ 01–03</span><h2>Подключите устройство к сети</h2></div>
        <StatusBadge tone={phaseTone}>{phaseLabel}</StatusBadge>
      </header>
      <div className="configuration-anchor">
        <span className="nodedc-field__description">
          Выберите направление связи. Каждый путь выполняет не более одного сетевого изменения и не повторяет его автоматически.
        </span>
        <Select
          label="Способ подключения"
          value={connectionMode}
          options={connectionModeOptions}
          onChange={(value) => {
            setConnectionMode(value);
            setSsid("");
            setPassword("");
            resetProvisioningIntent();
          }}
          disabled={isBusy}
          variant="split"
        />
      </div>
      <div className="wizard-list">
        <WizardStep number="01" title="Включите устройство" status={powerConfirmed ? "Подтверждено" : "Ожидает"} tone={powerConfirmed ? "success" : "warning"}>
          <div className="nodedc-field">
            <span className="nodedc-field__description">Для текущего адаптера дождитесь ровного зелёного индикатора. Это подтверждение оператора, а не аппаратная телеметрия.</span>
            <Checker
              checked={powerConfirmed}
              label="Устройство включено, индикатор стабилен"
              onChange={(checked) => { setPowerConfirmed(checked); if (!checked) resetProvisioningIntent(); }}
            />
          </div>
        </WizardStep>
        <WizardStep
          number="02"
          title="Выберите Bluetooth-устройство"
          status={pendingAction === "scan" ? "Поиск…" : selectedDeviceId ? "Устройство выбрано" : `Найдено: ${devices.length}`}
          tone={pendingAction === "scan" ? "accent" : selectedDeviceId ? "success" : "neutral"}
        >
          <p className="step-copy">Поиск занимает 6 секунд и показывает все видимые BLE-устройства. Метка кандидата основана только на имени; точные модель, platform type и прошивка будут проверены по живому DeviceInfo перед START.</p>
          <Button
            width="full"
            variant="secondary"
            icon={<Icon name="search" />}
            disabled={!powerConfirmed || isBusy}
            onClick={() => { setSelectedDeviceId(""); resetProvisioningIntent(); void scan(); }}
          >
            {pendingAction === "scan" ? "Сканируем Bluetooth — 6 секунд…" : "Показать все BLE-устройства"}
          </Button>
          <div className="device-list">
            {devices.length ? devices.map((device) => (
              <DeviceRow
                key={device.device_id}
                device={device}
                selected={device.device_id === selectedDeviceId}
                onSelect={() => { setSelectedDeviceId(device.device_id); resetProvisioningIntent(); }}
              />
            )) : <div className="empty-device-list">Устройства пока не найдены. Проверьте питание и повторите поиск.</div>}
          </div>
        </WizardStep>
        <WizardStep
          number="03"
          title={modeCopy.stepTitle}
          status={selectedModeConnected ? "Адрес получен" : "Ожидает подключения"}
          tone={selectedModeConnected ? "success" : "neutral"}
        >
          {connectionMode === "quick-connect" ? (
            <div className="connection-summary">
              <span>Канонический путь</span>
              <strong>BLE включает AP → macOS подключает Mac к AP выбранного K1</strong>
            </div>
          ) : (
            <div className="field-stack">
              <TextField label={modeCopy.ssidLabel ?? "Название сети Wi‑Fi"} hint="SSID" value={ssid} onChange={(event) => { setSsid(event.target.value); provisioningIntentRef.current = null; }} autoComplete="off" spellCheck={false} placeholder={modeCopy.ssidPlaceholder} />
              <TextField label="Пароль Wi‑Fi" hint="Только в оперативной памяти" type="password" value={password} onChange={(event) => { setPassword(event.target.value); provisioningIntentRef.current = null; }} autoComplete="off" placeholder="Введите пароль" />
            </div>
          )}
          <div className="connection-summary"><span>Устройство</span><strong>{deviceSummary?.name || selectedDeviceId || "Сначала выберите устройство"}</strong></div>
          <Button width="full" variant="primary" icon={<Icon name="network" />} disabled={!canConnect} onClick={() => void submitConnect()}>
            {pendingAction === "connect"
              ? connectionMode === "quick-connect" ? "Включаем точку и подключаем…" : "Подключаем…"
              : modeCopy.buttonLabel}
          </Button>
          <p className="safety-note">
            {modeCopy.safetyNote}
            {connectionMode === "quick-connect" ? " Это лабораторный путь для уже подготовленного хоста: credential provider должен существовать в системном хранилище заранее. На чистом Mac операция завершится до BLE-записи; браузер, API, журналы и evidence секрета не получают." : " Пароль передаётся только локальному сервису, не сохраняется в браузере и удаляется из формы после успеха."}
          </p>
        </WizardStep>
      </div>
    </GlassSurface>
  );
}
