<script>
  import { onMount } from 'svelte';
  import { page } from '$app/stores';
  import { getJSON, postJSON } from '$lib/api.js';
  import { auth, savedIds, refresh, toggleFollow } from '$lib/auth.svelte.js';
  import { prefs, initPrefs, persistPrefs } from '$lib/prefs.svelte.js';
  import { RITUAL_ITEMS, ritualKeys, DEFAULT_KEYS } from '$lib/ritual.js';
  import { history, initHistory, loadServerHistory, removeOne, clearAll, record } from '$lib/history.svelte.js';
  import { track } from '$lib/analytics.js';
  import { openFeedback } from '$lib/feedback.svelte.js';
  import AccountPanel from '$lib/components/AccountPanel.svelte';
  import BoundariesPanel from '$lib/components/BoundariesPanel.svelte';
  import LanePicker from '$lib/components/LanePicker.svelte';
  import ArticleCard from '$lib/components/ArticleCard.svelte';

  let section = $derived($page.url.searchParams.get('section') || 'profile');
  let historyItems = $derived(auth.user ? history.server : history.device);

  let savedItems = $state([]);
  let savedReady = $state(false);
  let lanePool = $state(null);

  const SECTIONS = [
    { key: 'profile', label: 'Profile' },
    { key: 'saved', label: 'Saved' },
    { key: 'following', label: 'Following' },
    { key: 'history', label: 'History' },
    { key: 'lanes', label: 'Lanes' },
    { key: 'calmset', label: 'Calm set' },
    { key: 'boundaries', label: 'Boundaries' },
  ];

  // Calm set: which daily items make up the reader's gentle daily ritual.
  let calmEnabled = $derived(new Set(ritualKeys(prefs.data.ritual)));
  function toggleCalmItem(key) {
    const cur = new Set(ritualKeys(prefs.data.ritual));
    cur.has(key) ? cur.delete(key) : cur.add(key);
    const keys = RITUAL_ITEMS.map((i) => i.key).filter((k) => cur.has(k));
    // null = "follow the curated default" (only when the selection IS the default);
    // otherwise store the explicit chosen list (frozen — future games won't auto-join).
    const isDefault = keys.length === DEFAULT_KEYS.length && DEFAULT_KEYS.every((k) => cur.has(k));
    prefs.data.ritual = isDefault ? null : keys;
    prefs.data = { ...prefs.data };
    persistPrefs();
  }

  let follows = $state([]);
  let followsReady = $state(false);
  async function loadFollowsList() {
    try { follows = await getJSON('/api/follows'); } catch { follows = []; }
  }
  async function removeFollow(f) {
    follows = follows.filter((x) => !(x.kind === f.kind && x.value === f.value)); // optimistic
    await toggleFollow(f.kind, f.value); // syncs the shared followKeys store too
  }

  onMount(async () => {
    if (!auth.ready) await refresh();
    initPrefs();
    initHistory();
    if (auth.user) loadServerHistory();
    try { lanePool = await getJSON('/api/lanes'); } catch { lanePool = null; }
  });

  let pinnedLaneKeys = $derived(
    prefs.data.lanes?.length ? prefs.data.lanes : (lanePool?.default ?? [])
  );
  function saveLanes(keys) {
    prefs.data.lanes = keys;
    persistPrefs();
  }

  let digestBusy = $state(false);
  async function toggleDigest() {
    if (!auth.user || digestBusy) return;
    digestBusy = true;
    try {
      await postJSON('/api/account/digest', { enabled: !auth.user.digest_enabled });
      await refresh(); // re-pull auth.user with the new digest_enabled
    } catch {
      /* leave as-is */
    } finally {
      digestBusy = false;
    }
  }

  // Load the saved grid when entering that section while signed in.
  $effect(() => {
    if (section === 'saved' && auth.user && !savedReady) {
      savedReady = true;
      getJSON('/api/saved').then((r) => (savedItems = r.items)).catch(() => {});
    }
    if (section === 'following' && auth.user && !followsReady) {
      followsReady = true;
      loadFollowsList();
    }
  });
  let savedShown = $derived(savedItems.filter((a) => savedIds.has(a.id)));
</script>

<header class="bar">
  <div class="container inner">
    <a class="brand" href="/" aria-label="Upbeat Bytes — home"><img class="logo" src="/logo.svg" alt="Upbeat Bytes" /></a>
    <div class="baractions">
      <button class="fb" onclick={openFeedback} aria-label="Share feedback" title="Share feedback">
        <svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><path d="M4 5h16v11H8l-4 3z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round" /></svg>
      </button>
      <a class="back" href="/"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M19 12H5M11 6l-6 6 6 6" fill="none" stroke="currentColor" stroke-width="2.1" stroke-linecap="round" stroke-linejoin="round"/></svg>Back</a>
    </div>
  </div>
</header>

<main class="container page">
  <h1>You</h1>

  <nav class="tabs" aria-label="Account sections">
    {#each SECTIONS as s (s.key)}
      <a href={'/account?section=' + s.key} class:active={section === s.key}>{s.label}</a>
    {/each}
    {#if auth.user?.is_admin}<a href="/admin" class="admin">Admin dashboard</a>{/if}
  </nav>

  <div class="content">
    {#if section === 'lanes'}
      {#if lanePool}
        <LanePicker inline pool={lanePool} selected={pinnedLaneKeys} onsave={saveLanes} />
      {:else}
        <p class="muted">Loading…</p>
      {/if}

    {:else if section === 'calmset'}
      <section class="panel">
        <h2>Your calm set</h2>
        <p class="dnote">The gentle daily loop shown on Highlights and Play — a finite "today's set"
          you can finish and feel caught up. Choose what fills yours, like building a workout. No
          pressure, no streaks; uncheck anything you'd rather not see there.</p>
        <ul class="calmpick">
          {#each RITUAL_ITEMS as it (it.key)}
            <li>
              <button class="cpitem" class:on={calmEnabled.has(it.key)} onclick={() => toggleCalmItem(it.key)}
                      aria-pressed={calmEnabled.has(it.key)}>
                <span class="cpmark" aria-hidden="true"></span>{it.label}
              </button>
            </li>
          {/each}
        </ul>
        {#if calmEnabled.size === 0}<p class="empty">Your calm set is empty — it won't show until you add something.</p>{/if}
      </section>

    {:else if section === 'boundaries'}
      <BoundariesPanel prefs={prefs.data} onchange={persistPrefs} />

    {:else if section === 'history'}
      <section class="panel">
        <div class="phead">
          <h2>History</h2>
          {#if historyItems.length}<button class="link" onclick={clearAll}>Clear all</button>{/if}
        </div>
        <p class="reassure">Stories you've opened or swapped away — so an accidental Replace stays
          recoverable. {auth.user ? 'Synced across your devices.' : 'Kept on this device.'}</p>
        {#if historyItems.length}
          <ul class="hist">
            {#each historyItems as a (a.id)}
              <li>
                <a href={a.url} target="_blank" rel="noopener" onclick={() => track('full_story', a.id)}>{a.title}</a>
                <span class="hsrc">{a.source}</span>
                <button class="hx" aria-label="Remove" onclick={() => removeOne(a.id)}>×</button>
              </li>
            {/each}
          </ul>
        {:else}
          <p class="empty">Nothing yet — stories you open or swap away will appear here.</p>
        {/if}
      </section>

    {:else if section === 'saved'}
      {#if !auth.user}
        <p class="gate">Sign in to save articles and find them here.</p>
      {:else if savedShown.length}
        <div class="grid">
          {#each savedShown as a (a.id)}
            <ArticleCard article={a} thumb onview={record} />
          {/each}
        </div>
      {:else if savedReady}
        <p class="empty">Nothing saved yet — tap <strong>Save</strong> on a story to keep it here.</p>
      {:else}
        <p class="muted">Loading…</p>
      {/if}

    {:else if section === 'following'}
      {#if !auth.user}
        <p class="gate">Sign in, then follow sources and topics to build your own calm lane.</p>
      {:else}
        <h2>Following</h2>
        <p class="dnote">Sources and topics you follow feed your <a href="/?view=following">Following</a> lane. Open any source or grouping and tap <strong>Follow</strong> to add it.</p>
        {#if follows.length}
          <ul class="follows">
            {#each follows as f (f.kind + ':' + f.value)}
              <li>
                <span class="fmeta"><span class="fkind">{f.kind}</span> <span class="fname">{f.kind === 'tag' ? f.name.replace(/-/g, ' ') : f.name}</span></span>
                <button class="funfollow" onclick={() => removeFollow(f)}>Unfollow</button>
              </li>
            {/each}
          </ul>
        {:else if followsReady}
          <p class="empty">You're not following anything yet.</p>
        {:else}
          <p class="muted">Loading…</p>
        {/if}
      {/if}

    {:else}
      <!-- profile -->
      {#if auth.user}
        <AccountPanel onclose={() => {}} />
        <section class="panel digest">
          <h2>Daily digest</h2>
          <p class="dnote">A calm morning email — today's handful of good things, with a one-tap unsubscribe. No streaks, no noise; just the brief in your inbox.</p>
          <button class="dtoggle" class:on={auth.user.digest_enabled} onclick={toggleDigest} disabled={digestBusy} aria-pressed={auth.user.digest_enabled}>
            {#if digestBusy}…{:else if auth.user.digest_enabled}✓ On — you'll get tomorrow's brief{:else}Get the daily digest{/if}
          </button>
        </section>
      {:else}
        <p class="gate">Sign in from the home page to manage your profile, saved articles, and devices.</p>
      {/if}
    {/if}
  </div>
</main>

<style>
  .bar { background: var(--surface); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 20; }
  .inner { display: flex; align-items: center; justify-content: space-between; height: 64px; }
  .logo { height: 40px; display: block; }
  .back { color: var(--accent-deep); font-size: 0.9rem; display: inline-flex; align-items: center; gap: 5px; }
  .back svg { width: 17px; height: 17px; display: block; }
  .baractions { display: flex; align-items: center; gap: 14px; }
  .baractions .fb { background: none; border: none; color: var(--accent-deep); cursor: pointer; display: inline-flex; padding: 2px; }
  .page { padding: 20px 20px 70px; }
  h1 { font-size: clamp(2rem, 5vw, 2.6rem); margin: 6px 0 16px; }

  /* Desktop: sidebar to the left of the content. Mobile: a top tab strip. */
  .tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 22px; }
  .tabs a {
    border: 1px solid var(--line); background: var(--surface); color: var(--ink);
    border-radius: 999px; padding: 7px 15px; font-size: 0.9rem;
  }
  .tabs a:hover { border-color: var(--accent); color: var(--accent-deep); }
  .tabs a.active { background: var(--accent); border-color: var(--accent); color: #fff; }
  .tabs a.admin { margin-left: auto; border-color: var(--accent); color: var(--accent-deep); }

  @media (min-width: 760px) {
    .page { display: grid; grid-template-columns: 180px 1fr; column-gap: 32px; align-items: start; }
    h1 { grid-column: 1 / -1; }
    .tabs { flex-direction: column; gap: 4px; position: sticky; top: 80px; }
    .tabs a { text-align: left; border-color: transparent; }
    .tabs a.admin { margin-left: 0; margin-top: 10px; }
  }

  .panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); padding: 20px 22px; }
  .digest { margin-top: 16px; }
  .digest h2 { font-size: 1.1rem; margin: 0 0 6px; }
  .dnote { color: var(--muted); font-size: 0.9rem; margin: 0 0 14px; line-height: 1.5; }
  .calmpick { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; max-width: 360px; }
  .cpitem {
    display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
    background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
    padding: 12px 16px; font: inherit; font-weight: 600; color: var(--muted); cursor: pointer;
    transition: border-color 0.14s ease, color 0.14s ease;
  }
  .cpitem.on { color: var(--ink); border-color: var(--accent); }
  .cpitem:hover { border-color: var(--accent); }
  .cpmark { width: 18px; height: 18px; border-radius: 50%; border: 1.5px solid var(--line); flex-shrink: 0;
            transition: background 0.14s ease, border-color 0.14s ease; }
  .cpitem.on .cpmark {
    background: var(--accent); border-color: var(--accent);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12l5 5 9-10' fill='none' stroke='white' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-size: 14px; background-repeat: no-repeat; background-position: center;
  }
  .dtoggle {
    font: inherit; font-size: 0.9rem; border-radius: 999px; padding: 9px 18px; cursor: pointer;
    border: 1px solid var(--accent); background: var(--surface); color: var(--accent-deep);
  }
  .dtoggle:hover { border-color: var(--accent-deep); }
  .dtoggle.on { background: var(--accent); border-color: var(--accent); color: #fff; }
  .dtoggle:disabled { opacity: 0.6; cursor: default; }
  ul.follows { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
  ul.follows li {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 11px 14px;
  }
  .fmeta { min-width: 0; }
  .fkind { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.07em; color: var(--muted); }
  .fname { font-weight: 600; color: var(--ink); text-transform: capitalize; margin-left: 6px; }
  .funfollow {
    flex-shrink: 0; background: none; border: 1px solid var(--line); color: var(--muted);
    border-radius: 999px; padding: 5px 13px; font-size: 0.8rem; cursor: pointer;
  }
  .funfollow:hover { border-color: #9a3b3b; color: #9a3b3b; }
  .phead { display: flex; align-items: baseline; justify-content: space-between; }
  .phead h2 { font-size: 1.3rem; }
  .link { background: none; border: none; color: var(--accent-deep); font-size: 0.85rem; text-decoration: underline; cursor: pointer; }
  .reassure { margin: 4px 0 14px; color: var(--muted); font-size: 0.85rem; }
  .hist { list-style: none; margin: 0; padding: 0; }
  .hist li { padding: 8px 0; border-bottom: 1px solid var(--line); display: flex; gap: 12px; align-items: baseline; }
  .hist li:last-child { border-bottom: none; }
  .hist a { color: var(--ink); }
  .hist a:hover { color: var(--accent-deep); }
  .hsrc { margin-left: auto; color: var(--muted); font-size: 0.78rem; white-space: nowrap; }
  .hx { background: none; border: none; color: var(--muted); font-size: 1.15rem; line-height: 1; cursor: pointer; padding: 0 2px; }
  .hx:hover { color: var(--accent-deep); }
  .empty { margin: 0; color: var(--muted); font-style: italic; font-size: 0.9rem; }
  .muted { color: var(--muted); }
  .gate { color: var(--muted); font-size: 1rem; padding: 8px 0; }
  .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(238px, 1fr)); gap: 18px; }
</style>
