import { initializeApp } from "https://www.gstatic.com/firebasejs/10.12.5/firebase-app.js";
import {
  getAuth,
  setPersistence,
  browserLocalPersistence,
  onAuthStateChanged,
  signOut
} from "https://www.gstatic.com/firebasejs/10.12.5/firebase-auth.js";
import {
  getFirestore,
  doc,
  getDoc,
  setDoc,
  serverTimestamp
} from "https://www.gstatic.com/firebasejs/10.12.5/firebase-firestore.js";

let auth = null;
let db = null;
let currentUser = null;

window.adminAuth = {
  getUser: () => currentUser,
  getIdToken: async (forceRefresh = false) => {
    if (!currentUser) return "";
    return await currentUser.getIdToken(forceRefresh);
  },
  logout: async () => {
    if (auth) {
      await signOut(auth);
    }
  },
  loadProfile: async () => {
    if (!db || !currentUser) return null;

    const ref = doc(db, "users", currentUser.uid);
    const snapshot = await getDoc(ref);

    if (!snapshot.exists()) {
      return {
        userId: currentUser.uid,
        email: currentUser.email || "",
        displayName: "",
        avatarUrl: "",
        avatarType: "",
        avatarPackId: "",
        avatarPackUrl: "",
        avatarIndex: -1
      };
    }

    return snapshot.data();
  },
  saveProfile: async (profile) => {
    if (!db || !currentUser) {
      throw new Error("Not logged in.");
    }

    const ref = doc(db, "users", currentUser.uid);

    await setDoc(ref, {
      userId: currentUser.uid,
      email: currentUser.email || "",
      displayName: profile.displayName || "",
      avatarUrl: profile.avatarUrl || "",
      avatarType: profile.avatarType || "",
      avatarPackId: profile.avatarPackId || "",
      avatarPackUrl: profile.avatarPackUrl || "",
      avatarIndex: Number.isFinite(Number(profile.avatarIndex)) ? Number(profile.avatarIndex) : -1,
      updatedAt: serverTimestamp()
    }, { merge: true });
  }
};

async function loadFirebaseConfig() {
  const response = await fetch("/api/public/firebase-web-config");
  const config = await response.json().catch(() => ({}));

  if (!response.ok) {
    throw new Error(config.error || "Could not load Firebase web config.");
  }

  return {
    apiKey: config.apiKey,
    authDomain: config.authDomain,
    projectId: config.projectId,
    appId: config.appId
  };
}


let lastCloudSessionSyncMs = 0;
let cloudSessionSyncInFlight = false;

async function syncLocalServerCloudSession(user, forceRefresh = false) {
  if (!user || cloudSessionSyncInFlight) return;

  cloudSessionSyncInFlight = true;

  try {
    const idToken = await user.getIdToken(forceRefresh);

    const response = await fetch("/api/admin/cloud-session", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${idToken}`
      },
      body: JSON.stringify({ idToken })
    });

    if (!response.ok) {
      const data = await response.json().catch(() => ({}));
      throw new Error(data.error || data.message || "Could not connect local server as logged-in user.");
    }

    lastCloudSessionSyncMs = Date.now();
  } finally {
    cloudSessionSyncInFlight = false;
  }
}

async function ensureLocalServerHasCloudSession(user, reason = "session_check") {
  if (!user) return;

  // Do not post the ID token repeatedly. The local check is cheap and avoids
  // touching Firestore. Only re-post when the local server reports that its
  // in-memory host session is missing, which commonly happens after a server
  // restart while this admin tab remains open.
  let data = null;
  try {
    const response = await fetch("/api/admin/server-config", { cache: "no-store" });
    data = await response.json().catch(() => null);
  } catch (error) {
    console.debug("Local server cloud-session check failed.", reason, error);
    return;
  }

  if (data && data.cloudUserConnected === false) {
    console.info("Local server lost host Firebase session; restoring from admin browser session.", reason);
    await syncLocalServerCloudSession(user, true);
    return;
  }

  // Firebase ID tokens expire. Keep the already-connected local host session
  // fresh, but only on a long interval so this does not become a noisy loop.
  if (Date.now() - lastCloudSessionSyncMs > 45 * 60 * 1000) {
    await syncLocalServerCloudSession(user, true);
  }
}

const firebaseConfig = await loadFirebaseConfig();
const app = initializeApp(firebaseConfig);

auth = getAuth(app);
db = getFirestore(app);

await setPersistence(auth, browserLocalPersistence);

onAuthStateChanged(auth, async user => {
  if (!user) {
    window.location.href = "/login";
    return;
  }

  currentUser = user;

  try {
    await syncLocalServerCloudSession(user, true);
  } catch (error) {
    console.error(error);
  }

  window.setInterval(() => {
    ensureLocalServerHasCloudSession(user, "heartbeat").catch(console.error);
  }, 10 * 1000);

  window.addEventListener("focus", () => {
    ensureLocalServerHasCloudSession(user, "window_focus").catch(console.error);
  });

  document.addEventListener("visibilitychange", () => {
    if (!document.hidden) {
      ensureLocalServerHasCloudSession(user, "visibility_change").catch(console.error);
    }
  });

  document.body.classList.add("admin-auth-ready");

  if (typeof window.onAdminAuthReady === "function") {
    window.onAdminAuthReady(user);
  }

  window.dispatchEvent(new CustomEvent("admin-auth-ready", { detail: { user } }));
});