import { defineStore } from "pinia";
import { ref } from "vue";
import { Store as TauriStore } from "@tauri-apps/plugin-store";
import type { SidecarConfig } from "@/lib/api";

const STORE_FILE = "config.json";
const KEY = "sidecar";

// A private overlay has no Threefold-operated seed peer. The user must
// declare bootstrap peers they trust (their own VPS, known friends…)
// before the daemon can usefully start.
const DEFAULT_CONFIG: SidecarConfig = {
  peers: [],
  tunName: null,
  noTun: false,
  networkName: null,
  tcpListenPort: null,
  quicListenPort: null,
};

function normalizePort(p: unknown): number | null {
  if (p === null || p === undefined || p === "" || p === 0) return null;
  const n = typeof p === "number" ? p : Number(p);
  if (!Number.isInteger(n) || n < 1 || n > 65535) return null;
  return n;
}

export const useConfigStore = defineStore("config", () => {
  const config = ref<SidecarConfig>({ ...DEFAULT_CONFIG });
  const loaded = ref(false);
  let store: TauriStore | null = null;

  async function ensureStore() {
    if (!store) store = await TauriStore.load(STORE_FILE);
    return store;
  }

  async function load() {
    const s = await ensureStore();
    const saved = await s.get<SidecarConfig>(KEY);
    if (saved) {
      config.value = {
        peers: Array.isArray(saved.peers) ? saved.peers : DEFAULT_CONFIG.peers,
        tunName: saved.tunName ?? null,
        noTun: !!saved.noTun,
        networkName: saved.networkName ?? null,
        tcpListenPort: normalizePort(saved.tcpListenPort),
        quicListenPort: normalizePort(saved.quicListenPort),
      };
    }
    loaded.value = true;
  }

  async function save(next: SidecarConfig) {
    config.value = {
      peers: next.peers.map((p) => p.trim()).filter(Boolean),
      tunName: next.tunName?.trim() ? next.tunName.trim() : null,
      noTun: !!next.noTun,
      networkName: next.networkName?.trim() ? next.networkName.trim() : null,
      tcpListenPort: normalizePort(next.tcpListenPort),
      quicListenPort: normalizePort(next.quicListenPort),
    };
    const s = await ensureStore();
    await s.set(KEY, config.value);
    await s.save();
  }

  function reset() {
    return save({ ...DEFAULT_CONFIG });
  }

  return { config, loaded, load, save, reset };
});
