import { computed, onMounted, reactive, ref, watch } from "vue";
import { auth, authFetch, login } from "@/auth";
import { formatActionError } from "./accountErrors";
import { useWolfDashboard } from "./useWolfDashboard";
/**
 * Build the Account page dashboard and admin action state.
 *
 * @returns {object} reactive service cards, admin state, and event handlers.
 */
export function useAccountDashboard() {
  const mailu = reactive({
    status: "loading",
    imap: "mail.bstein.dev:993 (TLS)",
    smtp: "mail.bstein.dev:587 (STARTTLS)",
    username: "",
    currentPassword: "",
    revealPassword: false,
    rotating: false,
    newPassword: "",
    error: "",
  });

  const jellyfin = reactive({
    status: "loading",
    username: "",
    syncStatus: "",
    syncDetail: "",
    error: "",
  });

  const vaultwarden = reactive({
    status: "loading",
    username: "",
    syncedAt: "",
    error: "",
  });

  const nextcloudMail = reactive({
    status: "loading",
    primaryEmail: "",
    accountCount: "",
    syncedAt: "",
    syncing: false,
    error: "",
  });

  const wger = reactive({
    status: "loading",
    username: "",
    password: "",
    passwordUpdatedAt: "",
    revealPassword: false,
    resetting: false,
    error: "",
  });

  const firefly = reactive({
    status: "loading",
    username: "",
    password: "",
    passwordUpdatedAt: "",
    revealPassword: false,
    resetting: false,
    error: "",
  });

  const { wolf, refreshWolf, unlockWolf, pairWolf, setWolfGameMode, adminUnlockWolfIp } = useWolfDashboard();

  const admin = reactive({
    enabled: false,
    loading: false,
    requests: [],
    error: "",
    acting: {},
    flags: [],
    flagsLoading: false,
    notes: {},
    selectedFlags: {},
  });
  const onboardingUrl = ref("/onboarding");
  const vaultwardenReady = computed(() => ["ready", "already_present", "active", "grandfathered"].includes(vaultwarden.status));
  const vaultwardenDisplayStatus = computed(() => (vaultwardenReady.value ? "ready" : vaultwarden.status));
  const vaultwardenOrder = computed(() => (vaultwardenReady.value ? 3 : 0));

  const doLogin = () => login("/account");

  const copied = reactive({});
  const normalizeEmail = (value) => (typeof value === "string" ? value.toLowerCase() : "");
  onMounted(() => {
    if (auth.ready && auth.authenticated) {
      refreshOverview();
      refreshWolf();
      refreshAdminRequests();
      refreshAdminFlags();
    } else {
      mailu.status = "login required";
      nextcloudMail.status = "login required";
      jellyfin.status = "login required";
      vaultwarden.status = "login required";
      wger.status = "login required";
      firefly.status = "login required";
      wolf.status = "login required";
    }
  });

  watch(
    () => [auth.ready, auth.authenticated],
    ([ready, authenticated]) => {
      if (!ready) return;
      if (!authenticated) {
        mailu.status = "login required";
        nextcloudMail.status = "login required";
        jellyfin.status = "login required";
        vaultwarden.status = "login required";
        wger.status = "login required";
        firefly.status = "login required";
        wolf.status = "login required";
        onboardingUrl.value = "/onboarding";
        admin.enabled = false;
        admin.requests = [];
        admin.flags = [];
        return;
      }
      refreshOverview();
      refreshWolf();
      refreshAdminRequests();
      refreshAdminFlags();
    },
    { immediate: false },
  );

  async function refreshOverview() {
    mailu.error = "";
    jellyfin.error = "";
    vaultwarden.error = "";
    nextcloudMail.error = "";
    wger.error = "";
    firefly.error = "";
    try {
      const resp = await authFetch("/api/account/overview", {
        headers: { Accept: "application/json" },
        cache: "no-store",
      });
      if (!resp.ok) {
        const data = await resp.json().catch(() => ({}));
        throw new Error(data?.error || `status ${resp.status}`);
      }
      const data = await resp.json();
      mailu.status = data.mailu?.status || "ready";
      mailu.username = normalizeEmail(data.mailu?.username) || normalizeEmail(auth.email) || auth.username;
      mailu.currentPassword = data.mailu?.app_password || "";
      nextcloudMail.status = data.nextcloud_mail?.status || "unknown";
      nextcloudMail.primaryEmail = normalizeEmail(data.nextcloud_mail?.primary_email) || "";
      nextcloudMail.accountCount = data.nextcloud_mail?.account_count || "";
      nextcloudMail.syncedAt = data.nextcloud_mail?.synced_at || "";
      wger.status = data.wger?.status || "unknown";
      wger.username = normalizeEmail(data.wger?.username) || mailu.username || auth.username;
      wger.password = data.wger?.password || "";
      wger.passwordUpdatedAt = data.wger?.password_updated_at || "";
      firefly.status = data.firefly?.status || "unknown";
      firefly.username = normalizeEmail(data.firefly?.username) || mailu.username || auth.username;
      firefly.password = data.firefly?.password || "";
      firefly.passwordUpdatedAt = data.firefly?.password_updated_at || "";
      vaultwarden.status = data.vaultwarden?.status || "unknown";
      vaultwarden.username = normalizeEmail(data.vaultwarden?.username) || mailu.username || auth.username;
      vaultwarden.syncedAt = data.vaultwarden?.synced_at || "";
      jellyfin.status = data.jellyfin?.status || "ready";
      jellyfin.username = data.jellyfin?.username || auth.username;
      jellyfin.syncStatus = data.jellyfin?.sync_status || "";
      jellyfin.syncDetail = data.jellyfin?.sync_detail || "";
      onboardingUrl.value = data.onboarding_url || "/onboarding";
    } catch (err) {
      mailu.status = "unavailable";
      nextcloudMail.status = "unavailable";
      wger.status = "unavailable";
      firefly.status = "unavailable";
      vaultwarden.status = "unavailable";
      jellyfin.status = "unavailable";
      jellyfin.syncStatus = "";
      jellyfin.syncDetail = "";
      onboardingUrl.value = "/onboarding";
      const message = err?.message ? `Failed to load account status (${err.message})` : "Failed to load account status.";
      mailu.error = message;
      nextcloudMail.error = message;
      wger.error = message;
      firefly.error = message;
      vaultwarden.error = message;
      jellyfin.error = message;
    }
  }

  async function refreshAdminRequests() {
    if (!auth.authenticated) {
      admin.enabled = false;
      admin.requests = [];
      return;
    }
    admin.error = "";
    admin.loading = true;
    try {
      const resp = await authFetch("/api/admin/access/requests", {
        headers: { Accept: "application/json" },
        cache: "no-store",
      });
      if (resp.status === 403) {
        admin.enabled = false;
        admin.requests = [];
        return;
      }
      if (!resp.ok) throw new Error(`status ${resp.status}`);
      const data = await resp.json();
      admin.enabled = true;
      admin.requests = Array.isArray(data.requests) ? data.requests : [];
      for (const req of admin.requests) {
        if (!req?.username) continue;
        if (!(req.username in admin.notes)) admin.notes[req.username] = "";
        if (!(req.username in admin.selectedFlags)) admin.selectedFlags[req.username] = [];
      }
    } catch (err) {
      admin.enabled = false;
      admin.requests = [];
      admin.error = err.message || "Failed to load access requests.";
    } finally {
      admin.loading = false;
    }
  }

  async function refreshAdminFlags() {
    if (!auth.authenticated) {
      admin.flags = [];
      admin.flagsLoading = false;
      return;
    }
    admin.flagsLoading = true;
    try {
      const resp = await authFetch("/api/admin/access/flags", {
        headers: { Accept: "application/json" },
        cache: "no-store",
      });
      if (resp.status === 403) {
        admin.flags = [];
        return;
      }
      if (!resp.ok) throw new Error(`status ${resp.status}`);
      const data = await resp.json();
      admin.flags = Array.isArray(data.flags) ? data.flags : [];
    } catch (err) {
      admin.flags = [];
      admin.error = admin.error || err.message || "Failed to load access flags.";
    } finally {
      admin.flagsLoading = false;
    }
  }

  function hasFlag(username, flag) {
    const selected = admin.selectedFlags[username];
    return Array.isArray(selected) && selected.includes(flag);
  }

  // WHY: admins need readable applicant names even when optional fields are missing; @returns display name.
  function formatName(req) {
    if (!req) return "unknown";
    const parts = [];
    if (req.first_name && String(req.first_name).trim()) {
      parts.push(String(req.first_name).trim());
    }
    if (req.last_name && String(req.last_name).trim()) {
      parts.push(String(req.last_name).trim());
    }
    return parts.length ? parts.join(" ") : "unknown";
  }

  function toggleFlag(username, flag, event) {
    const checked = Boolean(event?.target?.checked);
    const selected = Array.isArray(admin.selectedFlags[username]) ? [...admin.selectedFlags[username]] : [];
    const next = checked ? Array.from(new Set([...selected, flag])) : selected.filter((item) => item !== flag);
    admin.selectedFlags[username] = next;
  }

  async function rotateMailu() {
    mailu.error = "";
    mailu.newPassword = "";
    mailu.rotating = true;
    try {
      const resp = await authFetch("/api/account/mailu/rotate", { method: "POST" });
      const data = await resp.json().catch(() => ({}));
      if (!resp.ok) throw new Error(data.error || `status ${resp.status}`);
      mailu.newPassword = data.password || "";
      if (mailu.newPassword) {
        mailu.currentPassword = mailu.newPassword;
        mailu.revealPassword = true;
      }
      const syncEnabled = Boolean(data.sync_enabled);
      const syncOk = Boolean(data.sync_ok);
      const syncError = data.sync_error || "";
      let syncWarning = "";
      if (!syncEnabled) {
        mailu.status = "updated";
        syncWarning = "Mail sync is not configured; password may not take effect until an admin sync runs.";
      } else if (!syncOk) {
        mailu.status = "sync pending";
        syncWarning = syncError || "Mail sync did not confirm success yet. Try again in a moment.";
      } else {
        mailu.status = "updated";
      }
      await refreshOverview();
      if (syncWarning) mailu.error = syncWarning;
    } catch (err) {
      mailu.error = formatActionError(err, "Rotation failed");
    } finally {
      mailu.rotating = false;
    }
  }

  async function resetWger() {
    wger.error = "";
    wger.resetting = true;
    try {
      const resp = await authFetch("/api/account/wger/reset", { method: "POST" });
      const data = await resp.json().catch(() => ({}));
      if (!resp.ok) throw new Error(data.error || `status ${resp.status}`);
      if (data.password) {
        wger.password = data.password;
        wger.revealPassword = true;
      }
      await refreshOverview();
    } catch (err) {
      wger.error = formatActionError(err, "Reset failed");
    } finally {
      wger.resetting = false;
    }
  }

  async function resetFirefly() {
    firefly.error = "";
    firefly.resetting = true;
    try {
      const resp = await authFetch("/api/account/firefly/reset", { method: "POST" });
      const data = await resp.json().catch(() => ({}));
      if (!resp.ok) throw new Error(data.error || `status ${resp.status}`);
      if (data.password) {
        firefly.password = data.password;
        firefly.revealPassword = true;
      }
      await refreshOverview();
    } catch (err) {
      firefly.error = formatActionError(err, "Reset failed");
    } finally {
      firefly.resetting = false;
    }
  }

  async function syncNextcloudMail() {
    nextcloudMail.error = "";
    nextcloudMail.syncing = true;
    try {
      const resp = await authFetch("/api/account/nextcloud/mail/sync", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ wait: true }),
      });
      const data = await resp.json().catch(() => ({}));
      if (!resp.ok) throw new Error(data.error || `status ${resp.status}`);
      await refreshOverview();
    } catch (err) {
      const message = formatActionError(err, "Sync failed");
      if (message.toLowerCase().includes("ariadne is busy")) {
        nextcloudMail.error = "Ariadne is busy. Refresh in a moment; the sync may have completed.";
      } else {
        nextcloudMail.error = message;
      }
    } finally {
      nextcloudMail.syncing = false;
    }
  }

  // WHY: Safari/private-mode clipboard support varies; @returns whether fallback copy completed.
  function fallbackCopy(text) {
    const textarea = document.createElement("textarea");
    textarea.value = text;
    textarea.setAttribute("readonly", "");
    textarea.style.position = "fixed";
    textarea.style.top = "-9999px";
    textarea.style.left = "-9999px";
    document.body.appendChild(textarea);
    textarea.select();
    textarea.setSelectionRange(0, textarea.value.length);
    document.execCommand("copy");
    document.body.removeChild(textarea);
  }

  async function approve(username) {
    admin.error = "";
    admin.acting[username] = true;
    try {
      const flags = Array.isArray(admin.selectedFlags[username]) ? admin.selectedFlags[username] : [];
      const note = (admin.notes[username] || "").trim();
      const payload = {};
      if (flags.length) payload.flags = flags;
      if (note) payload.note = note;
      const resp = await authFetch(`/api/admin/access/requests/${encodeURIComponent(username)}/approve`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload),
      });
      if (!resp.ok) {
        const data = await resp.json().catch(() => ({}));
        throw new Error(data.error || `status ${resp.status}`);
      }
      await refreshAdminRequests();
    } catch (err) {
      admin.error = err.message || "Approve failed";
    } finally {
      admin.acting[username] = false;
    }
  }

  async function deny(username) {
    admin.error = "";
    admin.acting[username] = true;
    try {
      const note = (admin.notes[username] || "").trim();
      const payload = note ? { note } : {};
      const resp = await authFetch(`/api/admin/access/requests/${encodeURIComponent(username)}/deny`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload),
      });
      if (!resp.ok) {
        const data = await resp.json().catch(() => ({}));
        throw new Error(data.error || `status ${resp.status}`);
      }
      await refreshAdminRequests();
    } catch (err) {
      admin.error = err.message || "Deny failed";
    } finally {
      admin.acting[username] = false;
    }
  }

  async function copy(key, text) {
    if (!text) return;
    try {
      if (navigator?.clipboard?.writeText) {
        await navigator.clipboard.writeText(text);
      } else {
        fallbackCopy(text);
      }
      copied[key] = true;
      window.setTimeout(() => {
        copied[key] = false;
      }, 1500);
    } catch {
      try {
        fallbackCopy(text);
        copied[key] = true;
        window.setTimeout(() => {
          copied[key] = false;
        }, 1500);
      } catch {
        // ignore
      }
    }
  }

  return {
    auth,
    mailu,
    jellyfin,
    vaultwarden,
    nextcloudMail,
    wger,
    firefly,
    wolf,
    admin,
    onboardingUrl,
    vaultwardenReady,
    vaultwardenDisplayStatus,
    vaultwardenOrder,
    doLogin,
    copied,
    hasFlag,
    formatName,
    toggleFlag,
    rotateMailu,
    resetWger,
    resetFirefly,
    syncNextcloudMail,
    refreshWolf,
    unlockWolf,
    pairWolf,
    setWolfGameMode,
    adminUnlockWolfIp,
    approve,
    deny,
    copy,
  };
}
