/* global React, sbx */
// Social hub (Hub phase 6) — data layer for the community Home.
//
// All identity-level exposure is enforced SERVER-SIDE (hub.sql):
// teeing_up() and live_now() only ever return mutuals who haven't gone
// quiet. The client just renders what it's given.

// ─── Friends teeing up ────────────────────────────────────────────────
// → [rows, loading]: [{ kind:'window'|'seat'|'booked', handle, name, …,
// courseId, courseShort, dateStr, startMin, endMin, teeISO, token, groupId }]
function useTeeingUp(userId) {
  const [rows, setRows] = React.useState([]);
  const [loading, setLoading] = React.useState(true);

  const load = React.useCallback(async () => {
    if (!userId) { setRows([]); setLoading(false); return; }
    const { data, error } = await sbx.rpc('teeing_up');
    if (error) { setRows([]); setLoading(false); return; } // RPC not migrated yet
    const mapped = (data || []).map(r => ({
      kind: r.kind, userId: r.user_id, handle: r.handle, name: r.first_name,
      avatarUrl: r.avatar_url, sbx: r.sbx,
      courseId: r.course_id, courseShort: r.course_short, dateStr: r.play_date,
      startMin: r.start_min, endMin: r.end_min, teeISO: r.tee_time,
      token: r.token, groupId: r.group_id,
    }));
    // Soonest first: seats (urgent) → windows → booked, then by date.
    const kindRank = { seat: 0, window: 1, booked: 2 };
    mapped.sort((a, b) => (a.dateStr || '').localeCompare(b.dateStr || '') || (kindRank[a.kind] - kindRank[b.kind]));
    setRows(mapped.slice(0, 12));
    setLoading(false);
  }, [userId]);

  React.useEffect(() => { load(); }, [load]);
  React.useEffect(() => {
    const iv = setInterval(load, 60000);
    return () => clearInterval(iv);
  }, [load]);

  return [rows, loading];
}

// ─── Live now ─────────────────────────────────────────────────────────
// → { aggregates: [{course, n}], cards: [{matchId, course, handle, name,
// side, thru, aWins, bWins}] } — cards poll every 20s (spectating-lite).
function useLiveNow(userId) {
  const [data, setData] = React.useState({ aggregates: [], cards: [] });

  const load = React.useCallback(async () => {
    if (!userId) { setData({ aggregates: [], cards: [] }); return; }
    const { data: d, error } = await sbx.rpc('live_now');
    if (error || !d) return;
    setData({
      aggregates: d.aggregates || [],
      cards: (d.cards || []).map(c => ({
        matchId: c.match_id, course: c.course, handle: c.handle, name: c.name,
        avatarUrl: c.avatar_url, side: c.side, thru: c.thru, aWins: c.a_wins, bWins: c.b_wins,
      })),
    });
  }, [userId]);

  React.useEffect(() => { load(); }, [load]);
  React.useEffect(() => {
    const iv = setInterval(load, 20000);
    return () => clearInterval(iv);
  }, [load]);

  return data;
}

// ─── Rivalries ────────────────────────────────────────────────────────
// → [rivals]: [{ handle, name, meetings, wins, losses, halves, sbx }]
// 2 meetings = budding, 3+ = full rivalry (label client-side).
function useMyRivalries(userId) {
  const [rivals, setRivals] = React.useState([]);
  React.useEffect(() => {
    if (!userId) { setRivals([]); return undefined; }
    let on = true;
    (async () => {
      const { data, error } = await sbx.rpc('my_rivalries', { p_min: 2 });
      if (!on || error) return;
      setRivals((data || []).map(r => ({
        opponentId: r.opponent_id, handle: r.handle, name: r.first_name,
        avatarUrl: r.avatar_url, sbx: r.sbx, meetings: r.meetings,
        wins: r.wins, losses: r.losses, halves: r.halves, lastAt: r.last_at,
      })));
    })();
    return () => { on = false; };
  }, [userId]);
  return rivals;
}

// ─── Weekly recap ─────────────────────────────────────────────────────
// Your last 7 days from completed matches: → { played, w, l, h } (null
// while loading, false when zero matches). SBX + delta render from
// MOCK.USER (already real via useRealUserSync).
function useWeeklyRecap(userId) {
  const [recap, setRecap] = React.useState(null);
  React.useEffect(() => {
    if (!userId) { setRecap(false); return undefined; }
    let on = true;
    (async () => {
      const since = new Date(Date.now() - 7 * 86400000).toISOString();
      const { data, error } = await sbx.from('matches')
        .select('id, result, player_a, player_a2, player_b, player_b2, completed_at')
        .eq('status', 'completed')
        .gte('completed_at', since)
        .or(`player_a.eq.${userId},player_a2.eq.${userId},player_b.eq.${userId},player_b2.eq.${userId}`);
      if (!on) return;
      if (error || !data || data.length === 0) { setRecap(false); return; }
      let w = 0, l = 0, h = 0;
      data.forEach(m => {
        const mine = (m.player_a === userId || m.player_a2 === userId) ? 'A' : 'B';
        if (m.result === 'H') h += 1;
        else if (m.result === mine) w += 1;
        else if (m.result) l += 1;
      });
      setRecap({ played: data.length, w, l, h });
    })();
    return () => { on = false; };
  }, [userId]);
  return recap;
}

// ─── Privacy settings ─────────────────────────────────────────────────
async function updatePrivacy(userId, { rounds, live }) {
  const patch = {};
  if (rounds) patch.privacy_rounds = rounds;
  if (live) patch.privacy_live = live;
  const { error } = await sbx.from('profiles').update(patch).eq('id', userId);
  if (error) throw new Error(error.message || 'Could not save privacy settings.');
}

Object.assign(window, { useTeeingUp, useLiveNow, useMyRivalries, useWeeklyRecap, updatePrivacy });
