/* global React, API, APPS, AppIcon, Icon, rulesToPolicy, policyToRules, DEFAULT_POLICY */
const { useState: useK, useEffect: useKE, useRef: useKR } = React;

function cap1(s) { return s ? s.charAt(0).toUpperCase() + s.slice(1) : s; }

function KeyholderDashboard({ keyholder, onSignOut }) {
  const [tab, setTab] = useK("requests");
  const [pendingCount, setPendingCount] = useK(0);
  const [showPw, setShowPw] = useK(false);

  return (
    <div className="kh">
      <header className="kh-head">
        <div className="kh-brand"><span className="wm-dot"></span> Daylight</div>
        <div className="kh-right">
          <span className="kh-who"><span className="kh-badge">{(keyholder || "K").slice(0, 1).toUpperCase()}</span><span className="kh-whon">{keyholder}<small>Keyholder</small></span></span>
          <button className="kh-signout" onClick={() => setShowPw(true)}>Password</button>
          <button className="kh-signout" onClick={onSignOut}>Sign out</button>
        </div>
      </header>

      <nav className="kh-tabs">
        <button className={"kh-tab" + (tab === "requests" ? " on" : "")} onClick={() => setTab("requests")}>
          Requests {pendingCount > 0 && <span className="kh-dot">{pendingCount}</span>}
        </button>
        <button className={"kh-tab" + (tab === "devices" ? " on" : "")} onClick={() => setTab("devices")}>Devices</button>
        <button className={"kh-tab" + (tab === "rules" ? " on" : "")} onClick={() => setTab("rules")}>Rules</button>
      </nav>

      <main className="kh-main">
        {tab === "requests" && <RequestsTab onCount={setPendingCount} keyholder={keyholder} />}
        {tab === "devices" && <DevicesTab />}
        {tab === "rules" && <RulesTab />}
      </main>
      {showPw && <ChangePassword onClose={() => setShowPw(false)} />}
    </div>
  );
}

function ChangePassword({ onClose }) {
  const [cur, setCur] = useK(""); const [nw, setNw] = useK("");
  const [err, setErr] = useK(null); const [done, setDone] = useK(false); const [busy, setBusy] = useK(false);
  async function save() {
    setBusy(true); setErr(null);
    try { await API.call("/auth/password", { method: "POST", body: JSON.stringify({ currentPassword: cur, newPassword: nw }) }); setDone(true); }
    catch (e) { setErr(e.message); } finally { setBusy(false); }
  }
  return (
    <div className="kh-modal-scrim" onClick={onClose}>
      <div className="kh-modal" onClick={(e) => e.stopPropagation()}>
        <h3>Change password</h3>
        {done ? (
          <React.Fragment>
            <p className="kh-modal-sub">Done — your new password is set.</p>
            <button className="kh-btn ok big" onClick={onClose}>Close</button>
          </React.Fragment>
        ) : (
          <React.Fragment>
            <input className="kh-in" type="password" placeholder="Current password" value={cur} onChange={(e) => setCur(e.target.value)} />
            <input className="kh-in" type="password" placeholder="New password (min 6)" value={nw} onChange={(e) => setNw(e.target.value)} />
            {err && <div className="form-err">{err}</div>}
            <div className="kh-modal-row">
              <button className="kh-btn no" onClick={onClose}>Cancel</button>
              <button className="kh-btn ok" disabled={busy || !cur || !nw} onClick={save}>{busy ? "Saving…" : "Save"}</button>
            </div>
          </React.Fragment>
        )}
      </div>
    </div>
  );
}

/* ---------------- Requests ---------------- */
function RequestsTab({ onCount, keyholder }) {
  const [grants, setGrants] = useK([]);
  const [busy, setBusy] = useK(null);
  const [loaded, setLoaded] = useK(false);

  async function load() {
    try {
      const { grants } = await API.call("/grants?status=pending");
      setGrants(grants); onCount(grants.length); setLoaded(true);
    } catch (e) { setLoaded(true); }
  }
  useKE(() => { load(); const t = setInterval(load, 5000); return () => clearInterval(t); }, []);

  async function decide(id, what) {
    setBusy(id);
    try { await API.call("/grants/" + id + "/" + what, { method: "POST", body: "{}" }); await load(); }
    finally { setBusy(null); }
  }

  if (!loaded) return <div className="kh-empty">Loading…</div>;
  if (!grants.length) return (
    <div className="kh-empty">
      <div className="kh-sun"></div>
      <h3>No requests waiting.</h3>
      <p>When someone asks for borrowed time, it appears here for you to approve or deny.</p>
    </div>
  );

  return (
    <div className="kh-list">
      {grants.map((g) => {
        const app = (g.target && g.target.app) || "youtube";
        return (
          <div className="kh-req" key={g.id}>
            <AppIcon app={app} size={48} />
            <div className="kh-req-body">
              <div className="kh-req-top"><b>{g.device_owner || g.device_label || "A device"}</b> wants <b>{g.minutes} min</b> of {APPS[app] ? APPS[app].label : app}</div>
              {g.reason ? <div className="kh-req-why">"{g.reason}"</div> : <div className="kh-req-why dim">No reason given</div>}
              <div className="kh-req-meta">{g.device_label || ""}</div>
            </div>
            <div className="kh-req-actions">
              <button className="kh-btn ok" disabled={busy === g.id} onClick={() => decide(g.id, "approve")}>Approve</button>
              <button className="kh-btn no" disabled={busy === g.id} onClick={() => decide(g.id, "deny")}>Deny</button>
            </div>
          </div>
        );
      })}
    </div>
  );
}

/* ---------------- Devices ---------------- */
function DevicesTab() {
  const [devices, setDevices] = useK([]);
  const [label, setLabel] = useK("");
  const [platform, setPlatform] = useK("ipados");
  const [owner, setOwner] = useK("");
  const [newCode, setNewCode] = useK(null);
  const [busy, setBusy] = useK(false);

  async function load() { try { const { devices } = await API.call("/devices"); setDevices(devices); } catch (e) {} }
  useKE(() => { load(); }, []);

  async function add() {
    if (!label) return;
    setBusy(true);
    try {
      const r = await API.call("/devices", { method: "POST", body: JSON.stringify({ label, platform, owner }) });
      setNewCode({ code: r.enrollCode, label });
      setLabel(""); setOwner(""); await load();
    } finally { setBusy(false); }
  }
  async function repair(id, lbl) {
    const r = await API.call("/devices/" + id + "/repair", { method: "POST", body: "{}" });
    setNewCode({ code: r.enrollCode, label: lbl }); load();
  }
  async function remove(id, lbl) {
    if (!window.confirm("Remove " + lbl + "? This unpairs it and deletes its rules.")) return;
    await API.call("/devices/" + id, { method: "DELETE" }); load();
  }

  return (
    <div>
      {newCode && (
        <div className="kh-codecard">
          <div className="kh-code-h">Pairing code for <b>{newCode.label}</b></div>
          <div className="kh-code">{newCode.code}</div>
          <p>On that device, open <b>daylight.liberatethecaptive.org</b> → "This is my device" → enter this code. It works once.</p>
          <button className="kh-btn ghost" onClick={() => setNewCode(null)}>Done</button>
        </div>
      )}

      <div className="kh-card">
        <div className="kh-card-h">Add a device</div>
        <div className="kh-form">
          <input className="kh-in" placeholder="Name (e.g. Clark's iPad)" value={label} onChange={(e) => setLabel(e.target.value)} />
          <select className="kh-in" value={platform} onChange={(e) => setPlatform(e.target.value)}>
            <option value="ipados">iPad</option><option value="ios">iPhone</option><option value="android">Android</option>
          </select>
          <input className="kh-in" placeholder="Owner (e.g. Clark)" value={owner} onChange={(e) => setOwner(e.target.value)} />
          <button className="kh-btn ok" disabled={busy || !label} onClick={add}>Add</button>
        </div>
      </div>

      <div className="kh-list">
        {devices.map((d) => (
          <div className="kh-device" key={d.id}>
            <div className="kh-dev-ico">{d.platform === "android" ? "🤖" : "▢"}</div>
            <div className="kh-dev-body">
              <div className="kh-dev-name">{d.label} {d.owner ? <span className="kh-tagchip">{d.owner}</span> : null}</div>
              <div className="kh-dev-meta">
                {d.enroll_code ? <span className="kh-pair">unpaired · code {d.enroll_code}</span> : <span className="kh-ok">paired</span>}
                {d.last_seen_at ? " · last seen " + timeAgo(d.last_seen_at) : " · never synced"}
              </div>
            </div>
            <div className="kh-dev-actions">
              <button className="kh-mini" onClick={() => repair(d.id, d.label)}>Re-pair</button>
              <button className="kh-mini danger" onClick={() => remove(d.id, d.label)}>Remove</button>
            </div>
          </div>
        ))}
        {!devices.length && <div className="kh-empty small">No devices yet. Add one above to get a pairing code.</div>}
      </div>
    </div>
  );
}

/* ---------------- Rules ---------------- */
function RulesTab() {
  const [devices, setDevices] = useK([]);
  const [sel, setSel] = useK(null);
  const [policy, setPolicy] = useK(DEFAULT_POLICY);
  const [saved, setSaved] = useK(false);
  const [busy, setBusy] = useK(false);

  useKE(() => { (async () => { try { const { devices } = await API.call("/devices"); setDevices(devices); if (devices[0]) pick(devices[0].id); } catch (e) {} })(); }, []);

  async function pick(id) {
    setSel(id); setSaved(false);
    try { const { rules } = await API.call("/devices/" + id + "/policy"); setPolicy(rulesToPolicy(rules)); }
    catch (e) { setPolicy(DEFAULT_POLICY); }
  }
  function tog(key, val) { setPolicy((p) => ({ ...p, [key]: val })); setSaved(false); }
  function togApp(app) { setPolicy((p) => ({ ...p, blockApps: p.blockApps.includes(app) ? p.blockApps.filter((a) => a !== app) : [...p.blockApps, app] })); setSaved(false); }
  function togFeed(f) { setPolicy((p) => ({ ...p, killFeeds: p.killFeeds.includes(f) ? p.killFeeds.filter((x) => x !== f) : [...p.killFeeds, f] })); setSaved(false); }

  async function save() {
    if (!sel) return;
    setBusy(true);
    try { await API.call("/devices/" + sel + "/policy", { method: "PUT", body: JSON.stringify({ rules: policyToRules(policy) }) }); setSaved(true); }
    finally { setBusy(false); }
  }

  if (!devices.length) return <div className="kh-empty small">Add a device first (Devices tab), then set its rules here.</div>;

  const Toggle = ({ on, onClick }) => <button className={"kh-toggle" + (on ? " on" : "")} onClick={onClick}><span className="kh-knob"></span></button>;
  const Row = ({ app, title, sub, on, onClick }) => (
    <div className="kh-rule">
      <AppIcon app={app} size={40} />
      <div className="kh-rule-t"><div className="kh-rule-n">{title}</div><div className="kh-rule-s">{sub}</div></div>
      <Toggle on={on} onClick={onClick} />
    </div>
  );

  return (
    <div>
      {devices.length > 1 && (
        <div className="kh-devpick">
          {devices.map((d) => <button key={d.id} className={"kh-pillbtn" + (sel === d.id ? " on" : "")} onClick={() => pick(d.id)}>{d.label}</button>)}
        </div>
      )}

      <div className="kh-card">
        <div className="kh-card-h">Block entirely</div>
        <Row app="x" title="X (Twitter)" sub="App and web, no exceptions" on={policy.blockApps.includes("x")} onClick={() => togApp("x")} />
        <Row app="tiktok" title="TikTok" sub="App and web, no exceptions" on={policy.blockApps.includes("tiktok")} onClick={() => togApp("tiktok")} />
      </div>

      <div className="kh-card">
        <div className="kh-card-h">Kill the feed, keep the app</div>
        <Row app="shorts" title="YouTube Shorts" sub="Shorts gone · videos stay" on={policy.killFeeds.includes("shorts")} onClick={() => togFeed("shorts")} />
        <Row app="reels" title="Instagram Reels" sub="Reels gone · DMs stay" on={policy.killFeeds.includes("reels")} onClick={() => togFeed("reels")} />
        <Row app="facebook" title="Facebook Reels" sub="Reels gone · Marketplace stays" on={policy.killFeeds.includes("facebook")} onClick={() => togFeed("facebook")} />
      </div>

      <div className="kh-card">
        <div className="kh-card-h">Cap & allow</div>
        <div className="kh-rule">
          <AppIcon app="youtube" size={40} />
          <div className="kh-rule-t"><div className="kh-rule-n">YouTube daily cap</div><div className="kh-rule-s">Then it locks for the day</div></div>
          <div className="kh-caps">
            {[0, 15, 30, 60].map((m) => <button key={m} className={"kh-capbtn" + (policy.youtubeCap === m ? " on" : "")} onClick={() => tog("youtubeCap", m)}>{m === 0 ? "Off" : m + "m"}</button>)}
          </div>
        </div>
        <Row app="market" title="Facebook Marketplace" sub="Always allowed in Safari" on={policy.allowMarketplace} onClick={() => tog("allowMarketplace", !policy.allowMarketplace)} />
      </div>

      <div className="kh-save-row">
        <button className="kh-btn ok big" disabled={busy} onClick={save}>{busy ? "Saving…" : saved ? "Saved ✓" : "Save rules"}</button>
        <span className="kh-save-note">Pushes to the device within seconds.</span>
      </div>
    </div>
  );
}

function timeAgo(ts) {
  const s = Math.floor(Date.now() / 1000) - ts;
  if (s < 60) return s + "s ago";
  if (s < 3600) return Math.floor(s / 60) + "m ago";
  if (s < 86400) return Math.floor(s / 3600) + "h ago";
  return Math.floor(s / 86400) + "d ago";
}

Object.assign(window, { KeyholderDashboard });
