import { computed, reactive, watch } from "vue";
import { auth, authFetch } from "../auth";

const state = reactive({
  loading: false,
  loaded: false,
  status: "",
  onboardingUrl: "/onboarding",
  dashboardUrl: "/apps",
  accountUrl: "/account",
  accessAllowed: true,
  error: "",
});

let watcherStarted = false;
let requestToken = 0;

function normalizeInternalUrl(value, fallback) {
  if (typeof value !== "string" || !value.trim()) return fallback;
  try {
    const url = new URL(value, window.location.origin);
    if (url.origin === window.location.origin) return `${url.pathname}${url.search}${url.hash}`;
    return value;
  } catch {
    return value.startsWith("/") ? value : fallback;
  }
}

function resetState() {
  state.loading = false;
  state.loaded = false;
  state.status = "";
  state.onboardingUrl = "/onboarding";
  state.dashboardUrl = "/apps";
  state.accountUrl = "/account";
  state.accessAllowed = true;
  state.error = "";
}

async function refreshMemberState() {
  if (!auth.ready || !auth.authenticated) {
    resetState();
    return;
  }

  const token = (requestToken += 1);
  state.loading = true;
  state.error = "";

  try {
    const resp = await authFetch("/api/account/member-state", {
      headers: { Accept: "application/json" },
      cache: "no-store",
    });
    const data = await resp.json().catch(() => ({}));
    if (token !== requestToken) return;
    if (resp.status === 403) {
      state.loaded = true;
      state.status = "restricted";
      state.accessAllowed = false;
      state.onboardingUrl = "/request-access";
      state.dashboardUrl = "/apps";
      state.accountUrl = "/account";
      return;
    }
    if (!resp.ok) throw new Error(data.error || `status ${resp.status}`);
    state.loaded = true;
    state.accessAllowed = true;
    state.status = data.status || "unknown";
    state.onboardingUrl = normalizeInternalUrl(data.onboarding_url, "/onboarding");
    state.dashboardUrl = normalizeInternalUrl(data.dashboard_url, "/apps");
    state.accountUrl = normalizeInternalUrl(data.account_url, "/account");
  } catch (err) {
    if (token !== requestToken) return;
    state.loaded = true;
    state.status = "unknown";
    state.accessAllowed = true;
    state.error = err?.message || "Member state unavailable";
  } finally {
    if (token === requestToken) state.loading = false;
  }
}

function startWatcher() {
  if (watcherStarted) return;
  watcherStarted = true;
  watch(
    () => [auth.ready, auth.authenticated, auth.token],
    () => {
      refreshMemberState();
    },
    { immediate: true },
  );
}

function memberActionForState() {
  if (!auth.enabled) return null;
  if (!auth.ready) {
    return { kind: "loading", label: "Checking Session", to: "", secondary: "" };
  }
  if (!auth.authenticated) {
    return { kind: "signed-out", label: "Sign In", to: "", secondary: "/request-access" };
  }
  if (auth.emailVerified === false) {
    return {
      kind: "verify",
      label: "Continue Verification",
      to: normalizeInternalUrl(auth.accountUrl, "/request-access"),
      secondary: state.accountUrl,
    };
  }
  if (state.loading && !state.loaded) {
    return { kind: "loading", label: "Checking Account", to: "", secondary: state.accountUrl };
  }
  if (["pending_email_verification", "pending"].includes(state.status)) {
    return { kind: "pending", label: "Check Access Status", to: "/request-access", secondary: state.accountUrl };
  }
  if (["accounts_building", "awaiting_onboarding"].includes(state.status)) {
    return { kind: "onboarding", label: "Continue Onboarding", to: state.onboardingUrl, secondary: state.accountUrl };
  }
  if (state.status === "restricted" || !state.accessAllowed) {
    return { kind: "restricted", label: "Account Status", to: "/request-access", secondary: state.accountUrl };
  }
  return { kind: "ready", label: "Open Services", to: state.dashboardUrl, secondary: state.accountUrl };
}

export function useMemberAccessState() {
  startWatcher();
  return {
    auth,
    memberState: state,
    memberAction: computed(memberActionForState),
    refreshMemberState,
  };
}
