// URL → confirmed-track memory.
//
// When a user confirms "this page is playing <song>", we remember it in
// chrome.storage.local keyed by a NORMALIZED url, so:
//   • fast lookup — the next visit to that page resolves instantly, no
//     title-guessing or re-detection;
//   • later use — the owner exports the confirmations (like the crowd-sourced
//     timings) to fold the URL↔recording links back into the library.
//
// Pure storage + URL logic (no DOM), usable from the panel and the service
// worker. Tested in tests/confirms.test.mjs with a mock chrome.storage.local.
const KEY = "eleje_confirms";

// Collapse a URL to a stable key so ?t=30s, playlist params, www., trailing
// slashes etc. all map to the same page.
export function urlKey(url) {
  try {
    const u = new URL(url);
    const host = u.hostname.replace(/^www\./, "").toLowerCase();
    if (/(^|\.)youtube\.com$/.test(host)) {
      const v = u.searchParams.get("v");
      if (v) return "yt:" + v;
    }
    if (host === "youtu.be") {
      const id = u.pathname.slice(1);
      if (id) return "yt:" + id;
    }
    if (host === "open.spotify.com") {
      const m = u.pathname.match(/\/track\/([A-Za-z0-9]+)/);
      if (m) return "sp:" + m[1];
    }
    return host + u.pathname.replace(/\/+$/, "");   // generic: host + path, no query/hash
  } catch {
    return (url || "").trim();
  }
}

function hasStore() {
  return typeof chrome !== "undefined" && chrome.storage && chrome.storage.local;
}
async function readAll() {
  if (!hasStore()) return {};
  const o = await chrome.storage.local.get(KEY);
  return (o && o[KEY]) || {};
}
async function writeAll(map) {
  if (!hasStore()) return;
  await chrome.storage.local.set({ [KEY]: map });
}

// Confirmed song for a url, or null.
export async function getConfirm(url) {
  const map = await readAll();
  return map[urlKey(url)] || null;
}

// Remember `song` as the track for `url`. `song` is an index.json record.
export async function saveConfirm(url, song, source = "panel") {
  if (!url || !song || !song.id) return null;
  const map = await readAll();
  const rec = {
    key: urlKey(url), url, songId: song.id,
    t: song.t || "", o: song.o || "", s: song.s || "", y: song.y || "",
    source, at: Date.now(),
  };
  map[rec.key] = rec;
  await writeAll(map);
  return rec;
}

// Mark a url as "not a tango" so the overlay stays quiet there (kept in the same map, so it
// persists across loads and is mirrored to the dev sink alongside the confirmations).
export async function saveNotTango(url) {
  if (!url) return null;
  const map = await readAll();
  const rec = { key: urlKey(url), url, notTango: true, source: "overlay", at: Date.now() };
  map[rec.key] = rec;
  await writeAll(map);
  return rec;
}

export async function removeConfirm(url) {
  const map = await readAll();
  const k = urlKey(url);
  if (map[k]) { delete map[k]; await writeAll(map); return true; }
  return false;
}

export async function allConfirms() {
  return Object.values(await readAll()).sort((a, b) => (b.at || 0) - (a.at || 0));
}
export async function countConfirms() {
  return Object.keys(await readAll()).length;
}
export async function clearConfirms() {
  await writeAll({});
}
