import { create } from "zustand";
import { fetchNodes, type ServerNode } from "@/lib/api";

// GET /api/v1/nodes ещё не отдаёт список (бэкенда для него пока нет), поэтому
// временно используем статический список ниже. Вся логика загрузки с бэкенда
// (fetchNodes, фолбэк, обработка ошибок) оставлена как есть — когда API
// появится, достаточно переключить этот флаг в false.
const USE_STATIC_NODES = true;

// Статический список серверов-заглушка. У каждого сервера свой decoy-хост
// (SNI) — под него маскируется ClientHello при подключении именно к этому
// серверу, значение должно совпадать с --decoy-host на самом сервере.
export const STATIC_NODES: ServerNode[] = [
  {
    id: "nl-1",
    name: "Netherlands",
    countryCode: "nl",
    ipAddress: "147.45.43.70",
    port: 443,
    sni: "ubuntu.com",
    status: "online",
    currentLoad: 0,
    tunnelAddress: "10.0.0.1",
    tunnelPrefix: 24,
    tunnelDns: "10.0.0.2",
    tunnelMtu: 1450,
  },
  {
    id: "sg-1",
    name: "Singapore",
    countryCode: "sg",
    ipAddress: "45.76.161.137",
    port: 8443,
    sni: "debian.org",
    status: "online",
    currentLoad: 0,
    tunnelAddress: "10.0.0.1",
    tunnelPrefix: 24,
    tunnelDns: "10.0.0.2",
    tunnelMtu: 1450,
  },
];

// Резервный узел — используется, если бэкенд недоступен или вернул пустой
// список, чтобы приложение оставалось рабочим.
export const FALLBACK_NODE: ServerNode = STATIC_NODES[1];

interface NodesState {
  nodes: ServerNode[];
  selectedId: string | null;
  loading: boolean;
  error: string | null;
  usingFallback: boolean;
  loadNodes: () => Promise<void>;
  selectNode: (id: string) => void;
  getSelectedNode: () => ServerNode;
}

export const useNodesStore = create<NodesState>((set, get) => ({
  nodes: [],
  selectedId: null,
  loading: false,
  error: null,
  usingFallback: false,

  loadNodes: async () => {
    set({ loading: true, error: null });

    if (USE_STATIC_NODES) {
      set({ nodes: STATIC_NODES, usingFallback: false, loading: false });
    } else {
      try {
        const nodes = await fetchNodes();
        if (nodes.length === 0) {
          // Бэкенд жив, но узлов нет — не оставляем юзера без подключения.
          set({
            nodes: [FALLBACK_NODE],
            usingFallback: true,
            loading: false,
          });
        } else {
          set({ nodes, usingFallback: false, loading: false });
        }
      } catch (e) {
        console.error("Failed to load nodes:", e);
        set({
          nodes: [FALLBACK_NODE],
          usingFallback: true,
          loading: false,
          error: e instanceof Error ? e.message : String(e),
        });
      }
    }

    // Выбираем узел по умолчанию: наименее загруженный из доступных.
    if (!get().selectedId) {
      const best = [...get().nodes].sort(
        (a, b) => a.currentLoad - b.currentLoad,
      )[0];
      if (best) set({ selectedId: best.id });
    }
  },

  selectNode: (id) => set({ selectedId: id }),

  getSelectedNode: () => {
    const { nodes, selectedId } = get();
    return nodes.find((n) => n.id === selectedId) ?? nodes[0] ?? FALLBACK_NODE;
  },
}));
