// Supabase-backed sync for the schedule state.

function createScheduleSync() {
  const cfg = window.SCHEDULE_SYNC_CONFIG || {};
  const ready =
    cfg.supabaseUrl &&
    cfg.supabaseAnonKey &&
    !cfg.supabaseUrl.includes('PASTE_') &&
    !cfg.supabaseAnonKey.includes('PASTE_') &&
    window.supabase;

  if (!ready) {
    return {
      configured: false,
      async getSession() { return null; },
      onAuthChange() { return () => {}; },
      async signInWithEmail() { throw new Error('Supabase sync is not configured yet.'); },
      async signOut() {},
      async loadState() { return null; },
      async saveState() {},
    };
  }

  const client = window.supabase.createClient(cfg.supabaseUrl, cfg.supabaseAnonKey, {
    auth: {
      persistSession: true,
      autoRefreshToken: true,
      detectSessionInUrl: true,
    },
  });
  const rowId = cfg.rowId || 'main';

  async function requireSession() {
    const { data, error } = await client.auth.getSession();
    if (error) throw error;
    return data.session || null;
  }

  return {
    configured: true,
    async getSession() {
      return requireSession();
    },
    onAuthChange(cb) {
      const { data } = client.auth.onAuthStateChange((_event, session) => cb(session || null));
      return () => data.subscription.unsubscribe();
    },
    async signInWithEmail(email) {
      // Build a clean redirect URL pointing back at THIS deployment
      // (origin + pathname, no hash, no query). This must also be whitelisted
      // in Supabase → Authentication → URL Configuration → Redirect URLs,
      // otherwise Supabase silently falls back to the Site URL.
      const redirectTo = cfg.redirectTo || `${window.location.origin}${window.location.pathname}`;
      const { error } = await client.auth.signInWithOtp({
        email,
        options: { emailRedirectTo: redirectTo },
      });
      if (error) throw error;
    },
    async signOut() {
      const { error } = await client.auth.signOut();
      if (error) throw error;
    },
    async loadState() {
      const session = await requireSession();
      if (!session) return null;
      // Hard timeout so a network stall doesn't leave the UI on
      // "Loading cloud data..." forever.
      const query = client
        .from('schedule_plan_state')
        .select('payload, updated_at')
        .eq('id', rowId)
        .maybeSingle();
      const timeout = new Promise((_, rej) =>
        setTimeout(() => rej(new Error('Cloud load timed out (10s). Check Supabase URL config, RLS policies, or network.')), 10000)
      );
      const { data, error } = await Promise.race([query, timeout]);
      if (error) throw error;
      return data ? { payload: data.payload || {}, updatedAt: data.updated_at } : null;
    },
    async saveState(state) {
      const session = await requireSession();
      if (!session) return;
      const updatedAt = state._updatedAt || new Date().toISOString();
      const { error } = await client
        .from('schedule_plan_state')
        .upsert({
          id: rowId,
          payload: state,
          updated_at: updatedAt,
          updated_by: session.user.id,
        });
      if (error) throw error;
    },
    // Subscribe to realtime row changes from OTHER devices.
    // Returns an unsubscribe function. The callback receives the new payload
    // and its server timestamp whenever the shared row changes in the DB.
    subscribeToChanges(callback) {
      const channel = client
        .channel(`schedule_plan_state:${rowId}`)
        .on(
          'postgres_changes',
          {
            event: '*',
            schema: 'public',
            table: 'schedule_plan_state',
            filter: `id=eq.${rowId}`,
          },
          (msg) => {
            const row = msg.new || msg.record;
            if (!row) return;
            callback({ payload: row.payload || {}, updatedAt: row.updated_at, updatedBy: row.updated_by });
          }
        )
        .subscribe();
      return () => {
        try { client.removeChannel(channel); } catch (_) {}
      };
    },
  };
}

window.ScheduleSync = createScheduleSync();
