/* Daylight shared client lib — loaded first. No JSX here, just helpers on window. */

/* ---------- API ---------- */
const API = {
  async call(path, opts = {}) {
    const r = await fetch("/api" + path, {
      credentials: "same-origin",
      headers: { "content-type": "application/json" },
      ...opts,
    });
    const j = await r.json().catch(() => ({}));
    if (!r.ok) throw new Error(j.error || "HTTP " + r.status);
    return j;
  },
  deviceId() { return localStorage.getItem("dl_device"); },
  secret() { return localStorage.getItem("dl_secret"); },
  isPaired() { return !!(this.deviceId() && this.secret()); },
  pair(deviceId, secret) { localStorage.setItem("dl_device", deviceId); localStorage.setItem("dl_secret", secret); },
  unpair() { localStorage.removeItem("dl_device"); localStorage.removeItem("dl_secret"); },
  async dev(path, opts = {}) {
    const r = await fetch("/api/device/" + this.deviceId() + path, {
      headers: { "content-type": "application/json", authorization: "Bearer " + this.secret() },
      ...opts,
    });
    const j = await r.json().catch(() => ({}));
    if (!r.ok) throw new Error(j.error || "HTTP " + r.status);
    return j;
  },
};

/* ---------- policy <-> rules <-> display ----------
   The single source of truth for how the high-level toggles map to backend rule kinds,
   used by BOTH the keyholder editor and the device's read-only view. */
const FEED_TO_UI = { youtube_shorts: "shorts", instagram_reels: "reels", facebook_reels: "facebook" };
const UI_TO_FEED = { shorts: "youtube_shorts", reels: "instagram_reels", facebook: "facebook_reels" };

const DEFAULT_POLICY = { blockApps: [], killFeeds: [], youtubeCap: 0, allowMarketplace: false };

function rulesToPolicy(rules) {
  const p = { blockApps: [], killFeeds: [], youtubeCap: 0, allowMarketplace: false };
  (rules || []).forEach((r) => {
    if (r.kind === "app_block") p.blockApps = (r.target && r.target.apps) || [];
    else if (r.kind === "feed_block") p.killFeeds = ((r.target && r.target.feeds) || []).map((f) => FEED_TO_UI[f] || f);
    else if (r.kind === "time_limit") p.youtubeCap = (r.params && r.params.minutesPerDay) || 0;
    else if (r.kind === "web_allow") p.allowMarketplace = true;
  });
  return p;
}

function policyToRules(p) {
  const rules = [];
  if (p.blockApps && p.blockApps.length) rules.push({ kind: "app_block", target: { apps: p.blockApps }, priority: 10 });
  if (p.killFeeds && p.killFeeds.length) rules.push({ kind: "feed_block", target: { feeds: p.killFeeds.map((f) => UI_TO_FEED[f] || f) }, priority: 10 });
  if (p.youtubeCap) rules.push({ kind: "time_limit", target: { apps: ["youtube"] }, params: { minutesPerDay: p.youtubeCap }, priority: 20 });
  if (p.allowMarketplace) rules.push({ kind: "web_allow", target: { domains: ["facebook.com"] }, params: { note: "marketplace" }, priority: 30 });
  return rules;
}

function policyToDisplay(p) {
  const blocked = [], gBlock = [], gFeed = [], gCap = [], gAllow = [];
  (p.blockApps || []).forEach((a) => {
    blocked.push({ app: a, desc: "Blocked entirely", pill: "block", state: "Blocked" });
    gBlock.push({ app: a, desc: "App and web — no exceptions" });
  });
  const fmap = {
    shorts: { state: "Shorts off", desc: "Feed removed · videos stay", g: "Shorts hidden · regular videos play" },
    reels: { state: "Reels off", desc: "Feed removed · DMs stay", g: "Reels hidden · messages & posts stay" },
    facebook: { state: "Reels off", desc: "Reels gone · Marketplace stays", g: "Reels hidden · Marketplace stays" },
  };
  (p.killFeeds || []).forEach((f) => {
    const m = fmap[f] || { state: "Feed off", desc: "Feed removed", g: "Feed hidden" };
    blocked.push({ app: f, desc: m.desc, pill: "strip", state: m.state });
    gFeed.push({ app: f, desc: m.g });
  });
  if (p.youtubeCap) {
    blocked.push({ app: "youtube", desc: p.youtubeCap + " min / day", pill: "cap", state: "Capped" });
    gCap.push({ app: "youtube", desc: p.youtubeCap + " minutes per day, then locked" });
  }
  if (p.allowMarketplace) {
    blocked.push({ app: "market", desc: "Always open", pill: "allow", state: "Allowed" });
    gAllow.push({ app: "market", desc: "Facebook Marketplace, in Safari" });
  }
  const groups = [];
  if (gBlock.length) groups.push({ label: "Blocked entirely", rows: gBlock });
  if (gFeed.length) groups.push({ label: "Feeds removed, the rest stays", rows: gFeed });
  if (gCap.length) groups.push({ label: "Capped", rows: gCap });
  if (gAllow.length) groups.push({ label: "Always allowed", rows: gAllow });
  const statCount = (p.blockApps ? p.blockApps.length : 0) + (p.killFeeds ? p.killFeeds.length : 0) + (p.youtubeCap ? 1 : 0);
  return { blocked, groups, statCount, statCap: p.youtubeCap || 0, choices: ["youtube", "facebook"] };
}

function nowSec() { return Math.floor(Date.now() / 1000); }

Object.assign(window, { API, rulesToPolicy, policyToRules, policyToDisplay, DEFAULT_POLICY, nowSec });
