// MMSaves — per-tool save store. Used today by the Sports calculators
// (Pace Calculator first); designed to be opt-in for any tool.
//
// Storage strategy:
//   - localStorage is the primary, instant store under key `mm-saves`
//   - When the user is signed in, we mirror the same blob to Supabase
//     (table `sync`, kind = 'sport-saves') so saves follow them across
//     devices, just like favorites and recent
//   - On sign-in, pull() merges server data into the local store
//
// Schema:
//   localStorage["mm-saves"] = {
//     [toolId]: [
//       { id: string, ts: number, label: string, data: any },
//       ...
//     ]
//   }
//
// Capped at 50 saves per tool, 250 total — the goal is light personal
// memory, not full activity history.

(function () {
  const KEY = 'mm-saves';
  const PER_TOOL_CAP = 50;
  let _pushTimer = null;

  function readLocal() {
    try {
      const raw = localStorage.getItem(KEY);
      if (!raw) return {};
      const parsed = JSON.parse(raw);
      return (parsed && typeof parsed === 'object') ? parsed : {};
    } catch { return {}; }
  }
  function writeLocal(obj) {
    try { localStorage.setItem(KEY, JSON.stringify(obj)); } catch {}
    window.dispatchEvent(new CustomEvent('mm-saves-changed'));
    schedulePush(obj);
  }

  // Best-effort cloud push, debounced 1s so rapid edits collapse into one upsert.
  function schedulePush(obj) {
    const sb = window.getSupabase?.();
    if (!sb) return;
    clearTimeout(_pushTimer);
    _pushTimer = setTimeout(async () => {
      try {
        const { data: { user } } = await sb.auth.getUser();
        if (!user) return;
        await sb.from('sync').upsert({
          user_id: user.id,
          kind: 'sport-saves',
          data: obj,
          updated_at: new Date().toISOString(),
        });
      } catch {}
    }, 1000);
  }

  async function pull() {
    const sb = window.getSupabase?.();
    if (!sb) return false;
    try {
      const { data: { user } } = await sb.auth.getUser();
      if (!user) return false;
      const { data } = await sb.from('sync')
        .select('data').eq('user_id', user.id).eq('kind', 'sport-saves').maybeSingle();
      const remote = data?.data;
      if (!remote || typeof remote !== 'object') return false;
      const local = readLocal();
      // Merge by id; remote wins for ties.
      const merged = {};
      const keys = new Set([...Object.keys(local), ...Object.keys(remote)]);
      for (const k of keys) {
        const seen = new Set();
        const items = [...(remote[k] || []), ...(local[k] || [])]
          .filter((x) => x && x.id && !seen.has(x.id) && (seen.add(x.id), true))
          .sort((a, b) => (b.ts || 0) - (a.ts || 0))
          .slice(0, PER_TOOL_CAP);
        if (items.length) merged[k] = items;
      }
      try { localStorage.setItem(KEY, JSON.stringify(merged)); } catch {}
      window.dispatchEvent(new CustomEvent('mm-saves-changed'));
      return true;
    } catch { return false; }
  }

  function add(toolId, data, label) {
    if (!toolId) throw new Error('toolId required');
    const all = readLocal();
    const list = Array.isArray(all[toolId]) ? all[toolId] : [];
    const id = `${toolId}-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
    const entry = {
      id,
      ts: Date.now(),
      label: (label || '').toString().slice(0, 80),
      data,
    };
    all[toolId] = [entry, ...list].slice(0, PER_TOOL_CAP);
    writeLocal(all);
    return entry;
  }

  function listAll() { return readLocal(); }
  function listFor(toolId) { return readLocal()[toolId] || []; }
  function remove(toolId, id) {
    const all = readLocal();
    if (!Array.isArray(all[toolId])) return;
    const next = all[toolId].filter((x) => x.id !== id);
    if (next.length) all[toolId] = next; else delete all[toolId];
    writeLocal(all);
  }
  function clearTool(toolId) {
    const all = readLocal();
    if (!all[toolId]) return;
    delete all[toolId];
    writeLocal(all);
  }
  function totalCount() {
    const all = readLocal();
    return Object.values(all).reduce((sum, list) => sum + (Array.isArray(list) ? list.length : 0), 0);
  }

  // React hook — returns the current saves array for one tool, re-rendering
  // the component on any change anywhere.
  function useSaves(toolId) {
    const [, force] = React.useState(0);
    React.useEffect(() => {
      const onChange = () => force((v) => v + 1);
      window.addEventListener('mm-saves-changed', onChange);
      return () => window.removeEventListener('mm-saves-changed', onChange);
    }, []);
    return readLocal()[toolId] || [];
  }
  function useAllSaves() {
    const [, force] = React.useState(0);
    React.useEffect(() => {
      const onChange = () => force((v) => v + 1);
      window.addEventListener('mm-saves-changed', onChange);
      return () => window.removeEventListener('mm-saves-changed', onChange);
    }, []);
    return readLocal();
  }

  window.MMSaves = {
    add, remove, clearTool,
    list: listFor,
    listAll,
    totalCount,
    pull,
    useSaves,
    useAllSaves,
  };
})();
