/* Optional Supabase cloud-sync layer.

   The app works perfectly without this — localStorage stays the source of
   truth. When the user signs in and toggles sync on, we mirror the whole
   workspace to a single JSONB row per user (table: public.workspaces). */

(function () {
  const cfg = window.TVConfig || {};
  const SYNC_FLAG = "tree-view.sync.enabled.v1";

  let client = null;
  const listeners = new Set();

  function isConfigured() {
    return !!(cfg.supabaseUrl && cfg.supabaseAnonKey && window.supabase);
  }

  function getClient() {
    if (client) return client;
    if (!isConfigured()) return null;
    client = window.supabase.createClient(cfg.supabaseUrl, cfg.supabaseAnonKey, {
      auth: {
        detectSessionInUrl: true,
        persistSession: true,
        autoRefreshToken: true,
        flowType: "pkce",
      },
    });
    client.auth.onAuthStateChange((_event, session) => {
      listeners.forEach(cb => { try { cb(session?.user || null); } catch (_) {} });
    });
    return client;
  }

  async function getUser() {
    const c = getClient();
    if (!c) return null;
    const { data } = await c.auth.getUser();
    return data?.user || null;
  }

  function onAuthChange(cb) {
    listeners.add(cb);
    // Fire once with the current user
    getUser().then(u => cb(u)).catch(() => cb(null));
    return () => listeners.delete(cb);
  }

  async function signInWithMagicLink(email) {
    const c = getClient();
    if (!c) throw new Error("Supabase not configured");
    const { error } = await c.auth.signInWithOtp({
      email,
      options: { emailRedirectTo: window.location.origin + window.location.pathname },
    });
    if (error) throw error;
  }

  async function signInWithOAuth(provider) {
    const c = getClient();
    if (!c) throw new Error("Supabase not configured");
    const { error } = await c.auth.signInWithOAuth({
      provider,
      options: { redirectTo: window.location.origin + window.location.pathname },
    });
    if (error) throw error;
  }

  async function signOut() {
    const c = getClient();
    if (!c) return;
    await c.auth.signOut();
  }

  async function pullWorkspace() {
    const c = getClient();
    if (!c) return null;
    const u = await getUser();
    if (!u) return null;
    const { data, error } = await c
      .from("workspaces")
      .select("data, updated_at")
      .eq("user_id", u.id)
      .maybeSingle();
    if (error) throw error;
    return data ? { workspace: data.data, updatedAt: data.updated_at } : null;
  }

  async function pushWorkspace(workspace) {
    const c = getClient();
    if (!c) return;
    const u = await getUser();
    if (!u) return;
    const { error } = await c
      .from("workspaces")
      .upsert({ user_id: u.id, data: workspace }, { onConflict: "user_id" });
    if (error) throw error;
  }

  // Default to ON — opt-out, not opt-in. Only "0" disables it.
  function isSyncEnabled() {
    try { return localStorage.getItem(SYNC_FLAG) !== "0"; } catch (_) { return true; }
  }
  function setSyncEnabled(v) {
    try { localStorage.setItem(SYNC_FLAG, v ? "1" : "0"); } catch (_) {}
  }

  window.TVCloud = {
    isConfigured,
    getClient,
    getUser,
    onAuthChange,
    signInWithMagicLink,
    signInWithOAuth,
    signOut,
    pullWorkspace,
    pushWorkspace,
    isSyncEnabled,
    setSyncEnabled,
  };
})();
