import { reactive } from "vue";
import { auth, authFetch } from "@/auth";
import { formatActionError } from "./accountErrors";

const IP_DISCOVERY_URL = "https://api.ipify.org?format=json";

async function resolveClientIp() {
  const controller = new AbortController();
  const timeout = window.setTimeout(() => controller.abort(), 3000);
  try {
    const resp = await fetch(IP_DISCOVERY_URL, {
      headers: { Accept: "application/json" },
      cache: "no-store",
      signal: controller.signal,
    });
    const data = await resp.json().catch(() => ({}));
    return typeof data?.ip === "string" ? data.ip.trim() : "";
  } catch {
    return "";
  } finally {
    window.clearTimeout(timeout);
  }
}

function withSourceIp(path, sourceIp) {
  if (!sourceIp) return path;
  const query = new URLSearchParams({ source_ip: sourceIp });
  return `${path}?${query.toString()}`;
}

/**
 * Build the Wolf card state and actions for the Account page.
 *
 * @returns {object} reactive Wolf state plus refresh, unlock, pairing, and admin GPU actions.
 */
export function useWolfDashboard() {
  const wolf = reactive({
    status: "loading",
    error: "",
    loading: false,
    unlocking: false,
    pairing: {},
    actioning: "",
    manualUnlocking: false,
    canControlGpu: false,
    moonlightHost: "moonlight.bstein.dev",
    sourceIp: "",
    unlockTtlSeconds: 28800,
    gpuPriority: "unknown",
    gpuOwner: "unknown",
    gameModeStatus: "unknown",
    gameModeActive: false,
    localModel: "unknown",
    localModelLoaded: false,
    localInferenceReady: false,
    inferencePath: "fallback",
    selectedGame: "steam",
    note: "",
    manualIp: "",
    manualUser: "",
    clients: [],
    pendingPairRequests: [],
    activeUnlocks: [],
    sessions: [],
    apps: [],
    pinInputs: {},
  });

  async function refreshWolf() {
    if (!auth.authenticated) {
      wolf.status = "login required";
      return;
    }
    wolf.error = "";
    wolf.loading = true;
    try {
      const sourceIp = await resolveClientIp();
      const resp = await authFetch(withSourceIp("/api/account/wolf", sourceIp), {
        headers: { Accept: "application/json" },
        cache: "no-store",
      });
      const data = await resp.json().catch(() => ({}));
      if (!resp.ok) throw new Error(data?.error || data?.detail || `status ${resp.status}`);

      wolf.canControlGpu = Boolean(data.can_control_gpu);
      wolf.moonlightHost = data.moonlight?.host || "moonlight.bstein.dev";
      wolf.sourceIp = data.moonlight?.source_ip || "";
      wolf.unlockTtlSeconds = Number(data.moonlight?.unlock_ttl_seconds || 28800);
      wolf.gpuPriority = data.gpu?.priority || "unknown";
      const gameMode = data.gpu?.game_mode || {};
      wolf.gpuOwner = gameMode.gpu_owner || "unknown";
      wolf.gameModeStatus = gameMode.status || "unknown";
      wolf.gameModeActive = Boolean(gameMode.active);
      wolf.localModel = gameMode.model || "unknown";
      wolf.localModelLoaded = Boolean(gameMode.model_loaded);
      wolf.localInferenceReady = Boolean(gameMode.local_inference_ready);
      wolf.inferencePath = gameMode.inference_path || "fallback";
      wolf.clients = Array.isArray(data.wolf?.clients) ? data.wolf.clients : [];
      wolf.pendingPairRequests = Array.isArray(data.wolf?.pending_pair_requests) ? data.wolf.pending_pair_requests : [];
      wolf.sessions = Array.isArray(data.wolf?.sessions) ? data.wolf.sessions : [];
      wolf.apps = Array.isArray(data.wolf?.apps) ? data.wolf.apps : [];
      wolf.activeUnlocks = Array.isArray(data.firewall?.active_unlocks) ? data.firewall.active_unlocks : [];
      for (const req of wolf.pendingPairRequests) {
        const key = req?.pair_secret || req?.name;
        if (key && !(key in wolf.pinInputs)) wolf.pinInputs[key] = "";
      }
      wolf.status = data.wolf?.api_enabled ? "ready" : "degraded";
    } catch (err) {
      wolf.status = "unavailable";
      wolf.error = formatActionError(err, "Wolf status unavailable");
    } finally {
      wolf.loading = false;
    }
  }

  async function unlockWolf() {
    wolf.error = "";
    wolf.unlocking = true;
    try {
      const sourceIp = await resolveClientIp();
      const resp = await authFetch("/api/account/wolf/firewall/unlock", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(sourceIp ? { ip: sourceIp } : {}),
      });
      const data = await resp.json().catch(() => ({}));
      if (!resp.ok) throw new Error(data?.error || data?.detail || `status ${resp.status}`);
      await refreshWolf();
    } catch (err) {
      wolf.error = formatActionError(err, "Unlock failed");
    } finally {
      wolf.unlocking = false;
    }
  }

  async function pairWolf(pairSecret) {
    if (!pairSecret) return;
    wolf.error = "";
    wolf.pairing[pairSecret] = true;
    try {
      const pin = wolf.pinInputs[pairSecret] || "";
      const sourceIp = await resolveClientIp();
      const resp = await authFetch("/api/account/wolf/pairing/submit-pin", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ pair_secret: pairSecret, pin, ...(sourceIp ? { source_ip: sourceIp } : {}) }),
      });
      const data = await resp.json().catch(() => ({}));
      if (!resp.ok) throw new Error(data?.error || data?.detail || `status ${resp.status}`);
      wolf.pinInputs[pairSecret] = "";
      await refreshWolf();
    } catch (err) {
      wolf.error = formatActionError(err, "Pairing failed");
    } finally {
      wolf.pairing[pairSecret] = false;
    }
  }

  async function setWolfGameMode(action) {
    wolf.error = "";
    wolf.actioning = action;
    try {
      const resp = await authFetch(`/api/account/wolf/game-mode/${action}`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ game: wolf.selectedGame, note: wolf.note }),
      });
      const data = await resp.json().catch(() => ({}));
      if (!resp.ok) throw new Error(data?.error || data?.detail || `status ${resp.status}`);
      await refreshWolf();
    } catch (err) {
      wolf.error = formatActionError(err, "GPU priority update failed");
    } finally {
      wolf.actioning = "";
    }
  }

  async function adminUnlockWolfIp() {
    if (!wolf.manualIp) return;
    wolf.error = "";
    wolf.manualUnlocking = true;
    try {
      const payload = { ip: wolf.manualIp };
      if (wolf.manualUser) payload.target_user = wolf.manualUser;
      const resp = await authFetch("/api/account/wolf/admin/firewall/unlock", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload),
      });
      const data = await resp.json().catch(() => ({}));
      if (!resp.ok) throw new Error(data?.error || data?.detail || `status ${resp.status}`);
      wolf.manualIp = "";
      wolf.manualUser = "";
      await refreshWolf();
    } catch (err) {
      wolf.error = formatActionError(err, "Manual unlock failed");
    } finally {
      wolf.manualUnlocking = false;
    }
  }

  return { wolf, refreshWolf, unlockWolf, pairWolf, setWolfGameMode, adminUnlockWolfIp };
}
