import { useEffect, useState } from "react";
import { Button, ControlRow, Icon, SettingsCard, TextField } from "@nodedc/ui-react";

type CesiumIonSecretStatus = {
  configured: boolean;
  updatedAt: string | null;
  verification?: "verified" | "failed" | "not-configured";
};

type MapGatewayHealth = {
  referenceSources?: {
    transportStations?: {
      profileId?: string;
      seedFactCount?: number;
      fetchEnabled?: boolean;
      cellDegrees?: number;
      cachedCellCount?: number;
      lastRefreshAt?: string | null;
    };
  };
};

export function FoundryMapProviderSettings() {
  const [token, setToken] = useState("");
  const [status, setStatus] = useState<CesiumIonSecretStatus | null>(null);
  const [gateway, setGateway] = useState<MapGatewayHealth | null>(null);
  const [saveState, setSaveState] = useState<"loading" | "idle" | "saving" | "saved" | "error">("loading");
  const [error, setError] = useState("");

  useEffect(() => {
    let active = true;
    setSaveState("loading");
    void Promise.all([
      fetch("/api/platform-settings/cesium-ion", { cache: "no-store" })
        .then((response) => response.ok ? response.json() as Promise<CesiumIonSecretStatus> : Promise.reject()),
      fetch("/api/map-gateway/healthz", { cache: "no-store" })
        .then((response) => response.ok ? response.json() as Promise<MapGatewayHealth> : null),
    ]).then(([nextStatus, nextGateway]) => {
      if (!active) return;
      setStatus(nextStatus);
      setGateway(nextGateway);
      setSaveState("idle");
    }).catch(() => {
      if (active) setSaveState("error");
    });
    return () => { active = false; };
  }, []);

  const save = async () => {
    const value = token.trim();
    if (value.length < 16) return;
    setSaveState("saving");
    setError("");
    try {
      const response = await fetch("/api/platform-settings/cesium-ion", {
        method: "PUT",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ token: value }),
      });
      if (!response.ok) {
        const result = await response.json().catch(() => null) as { error?: string } | null;
        throw new Error(result?.error || "platform_settings_save_failed");
      }
      setStatus(await response.json() as CesiumIonSecretStatus);
      setToken("");
      setSaveState("saved");
    } catch (cause) {
      const code = cause instanceof Error ? cause.message : "platform_settings_save_failed";
      setError(code === "cesium_ion_token_verification_failed"
        ? "Token не прошёл проверку terrain, imagery и 3D Buildings. Старое значение сохранено."
        : code === "map_gateway_admin_unauthorized"
          ? "Внутренний signing profile Gateway не совпадает с Foundry."
          : "Не удалось применить token. Проверьте права администратора и доступность Gateway.");
      setSaveState("error");
    }
  };

  const stations = gateway?.referenceSources?.transportStations;
  return (
    <div className="catalog-form">
      <SettingsCard
        eyebrow="MAP PROVIDERS"
        title="Cesium Ion"
        description="Master token хранится только в закрытом хранилище Platform Map Gateway. После применения он не отображается и не попадает в browser, env ответа или Application artifact."
      >
        <ControlRow label="Состояние">
          <strong>{saveState === "loading" ? "Проверяем…" : status?.configured ? "Настроен" : "Не настроен"}</strong>
        </ControlRow>
        {status?.configured ? (
          <ControlRow label="Проверка provider">
            <strong>{status.verification === "verified" ? "Пройдена: terrain, imagery и 3D доступны" : "Не пройдена"}</strong>
          </ControlRow>
        ) : null}
        {status?.updatedAt ? <small>Последнее изменение: {new Date(status.updatedAt).toLocaleString()}</small> : null}
      </SettingsCard>
      <TextField
        type="password"
        autoComplete="new-password"
        label="Cesium Ion token"
        hint="обязательно"
        description="Вставьте новый token. Существующее значение намеренно нельзя прочитать обратно."
        value={token}
        onChange={(event) => {
          setToken(event.target.value);
          if (saveState === "saved" || saveState === "error") setSaveState("idle");
          setError("");
        }}
      />
      <Button
        variant="primary"
        shape="pill"
        icon={<Icon name="save" />}
        disabled={saveState === "loading" || saveState === "saving" || token.trim().length < 16}
        onClick={() => { void save(); }}
      >{saveState === "saving" ? "Применение…" : "Применить Cesium token"}</Button>
      {saveState === "saved" ? <small className="catalog-application-draft__status">Token применён в Platform Map Gateway.</small> : null}
      {saveState === "error" && error ? <small className="catalog-application-draft__status" data-state="error">{error}</small> : null}

      <SettingsCard
        eyebrow="MAP REFERENCE SOURCE"
        title="OpenStreetMap · транспортные станции"
        description="Token не требуется. Map Gateway нормализует только разрешённые поля map.station/map.terminal; raw OSM payload и provider endpoint не попадают в Foundry."
      >
        <ControlRow label="Профиль"><strong>{stations?.profileId ?? "transport-stations.v1"}</strong></ControlRow>
        <ControlRow label="Начальный snapshot"><strong>{stations?.seedFactCount ?? 638} точек</strong></ControlRow>
        <ControlRow label="Пространственный кэш"><strong>{stations ? `${stations.cachedCellCount ?? 0} ячеек · ${stations.cellDegrees ?? 0.5}°` : "проверяется…"}</strong></ControlRow>
        <ControlRow label="Подгрузка"><strong>{stations?.fetchEnabled === false ? "только snapshot" : "по viewport, через Gateway"}</strong></ControlRow>
        {stations?.lastRefreshAt ? <small>Последнее пополнение: {new Date(stations.lastRefreshAt).toLocaleString()}</small> : null}
      </SettingsCard>
    </div>
  );
}
