/* ============ app.jsx — root app, Clerk-aware session, real data ============ */

const { useState: useStateA, useEffect: useEffectA, useMemo: useMemoA } = React;

const TWEAK_DEFAULTS = { theme: "green" };

/* Persistent lending state lives in localStorage in Phase 1.
   Phase 2 will replace this with /api/loans, /api/holds, /api/wishlist. */
function loadLending(){
  try { return JSON.parse(localStorage.getItem('mcmrs_lending') || '{}'); } catch { return {}; }
}
function saveLending(s){
  try { localStorage.setItem('mcmrs_lending', JSON.stringify(s)); } catch {}
}

function App(){
  /* ------- routing ------- */
  const [route, setRoute] = useStateA(() => {
    try {
      const raw = localStorage.getItem('mcmrs_route');
      if (raw) return JSON.parse(raw);
    } catch(e){}
    return { name:'home' };
  });
  const go = (r) => {
    setRoute(r);
    try { localStorage.setItem('mcmrs_route', JSON.stringify(r)); } catch(e){}
    window.scrollTo(0, 0);
  };

  /* ------- Clerk session ------- */
  const [clerkReady, setClerkReady] = useStateA(false);
  const [user, setUser] = useStateA(null);
  const [me, setMe] = useStateA(null);   // /api/me payload (id, name, isAdmin)

  useEffectA(() => {
    let cancelled = false;
    (async () => {
      // Wait for the Clerk script to finish loading
      while (!window.Clerk && !cancelled) {
        await new Promise(r => setTimeout(r, 50));
      }
      if (cancelled) return;
      try {
        // load() is idempotent — Clerk's auto-init may have already done it
        await window.Clerk.load();
        window.Clerk.addListener(() => {
          if (cancelled) return;
          setUser(window.Clerk.user || null);
        });
        setUser(window.Clerk.user || null);
        setClerkReady(true);
      } catch (e) {
        console.error('Clerk load failed:', e);
        setClerkReady(true);  // unblock UI so login page shows
      }
    })();
    return () => { cancelled = true; };
  }, []);

  /* Hide the boot screen once Clerk is ready */
  useEffectA(() => {
    if (clerkReady) {
      const el = document.getElementById('boot');
      if (el) {
        el.classList.add('hide');
        setTimeout(() => el && el.remove(), 500);
      }
    }
  }, [clerkReady]);

  /* When a Clerk user appears while we're on the login page, route onward */
  useEffectA(() => {
    if (user && route.name === 'login') {
      go(route.next || { name:'home' });
    }
  }, [user]);

  /* ------- /api/me (for isAdmin + canonical display name) ------- */
  useEffectA(() => {
    if (!user) { setMe(null); return; }
    (async () => {
      try { setMe(await window.api('/api/me')); }
      catch(e) { console.error('me:', e); }
    })();
  }, [user]);

  /* ------- catalogue data from the API ------- */
  const [data, setData] = useStateA(null);
  const [loadErr, setLoadErr] = useStateA(null);
  const reload = async () => {
    try {
      const [booksRes, filtersRes] = await Promise.all([
        window.api('/api/books?limit=1000'),
        window.api('/api/filters'),
      ]);
      const books = booksRes.books;
      setData({
        books,
        regions:  filtersRes.regions  || [],
        eras:     filtersRes.eras     || [],
        scales:   filtersRes.scales   || [],
        subjects: filtersRes.subjects || [],
        langs:    filtersRes.langs    || [],
      });
      setLoadErr(null);
    } catch (e) {
      console.error('catalogue load:', e);
      setLoadErr(e.message || 'Could not load the catalogue.');
    }
  };
  useEffectA(() => {
    if (user) reload();
  }, [user]);

  /* ------- lending state (Phase 1: localStorage; Phase 2: API) ------- */
  const [lending, setLendingRaw] = useStateA(() => {
    const s = loadLending();
    return {
      loans:    Array.isArray(s.loans)    ? s.loans    : [],
      history:  Array.isArray(s.history)  ? s.history  : [],
      wishlist: Array.isArray(s.wishlist) ? s.wishlist : [],
    };
  });
  const setLending = (next) => { setLendingRaw(next); saveLending(next); };

  /* Compose the session object the design's pages expect */
  const session = useMemoA(() => {
    if (!user) return null;
    const name =
      user.fullName ||
      [user.firstName, user.lastName].filter(Boolean).join(' ') ||
      user.username ||
      (user.primaryEmailAddress && user.primaryEmailAddress.emailAddress) ||
      'Member';
    return {
      name,
      email: (user.primaryEmailAddress && user.primaryEmailAddress.emailAddress) || '',
      member: 'MCMRS-' + (user.id || '').slice(-6).toUpperCase(),
      loans:    lending.loans,
      history:  lending.history,
      wishlist: lending.wishlist,
    };
  }, [user, lending]);

  /* ------- borrow / return / renew / wishlist (Phase 1 mock) ------- */
  const onAuth = () => { /* no-op: Clerk does the auth */ };

  const onBorrow = (book, held) => {
    if (!session) return;
    const ref = 'MCMRS-' + Math.floor(Math.random()*9000 + 1000);
    if (!held){
      const now = new Date();
      const due = new Date(now); due.setDate(due.getDate() + 42);
      const newLoan = {
        bookId: book.id,
        borrowed: now.toISOString().slice(0,10),
        due:      due.toISOString().slice(0,10),
        ref,
      };
      setLending({ ...lending, loans: [newLoan, ...lending.loans] });
    }
    go({ name:'confirm', id: book.id, ref, held: !!held });
  };

  const onReturn = (loan) => {
    if (!session) return;
    setLending({
      ...lending,
      loans: lending.loans.filter(l => l !== loan),
      history: [
        { bookId: loan.bookId, borrowed: loan.borrowed, returned: new Date().toISOString().slice(0,10) },
        ...lending.history,
      ],
    });
  };

  const onRenew = (loan) => {
    if (!session) return;
    const d = new Date(loan.due);
    d.setDate(d.getDate() + 42);
    setLending({
      ...lending,
      loans: lending.loans.map(l => l === loan ? { ...l, due: d.toISOString().slice(0,10) } : l),
    });
  };

  const wishlistToggle = (id) => {
    if (!session) return;
    const list = lending.wishlist.includes(id)
      ? lending.wishlist.filter(x => x !== id)
      : [id, ...lending.wishlist];
    setLending({ ...lending, wishlist: list });
  };

  /* ------- theme picker ------- */
  const [theme, setTheme] = useStateA(() => {
    try { return localStorage.getItem('mcmrs_theme') || TWEAK_DEFAULTS.theme; }
    catch { return TWEAK_DEFAULTS.theme; }
  });
  useEffectA(() => {
    document.documentElement.setAttribute('data-theme', theme);
    try { localStorage.setItem('mcmrs_theme', theme); } catch {}
  }, [theme]);
  const [tweaksVisible, setTweaksVisible] = useStateA(true);  // always-on in production for now

  /* ------- footer stats ------- */
  const stats = useMemoA(() => {
    if (!data) return null;
    const yr = new Date().getFullYear();
    return {
      total: data.books.length,
      onLoan: data.books.reduce((s,b) => s + (b.onLoan||0), 0),
      addedThisYear: data.books.filter(b => (b.created_at||'').startsWith(String(yr))).length,
    };
  }, [data]);

  /* ------- render ------- */
  // Not signed in → take everyone to login screen except home/browse/search/book (public-ish viewer)
  // But the API requires auth, so home etc. will be blocked without user. Send to login.
  if (clerkReady && !user) {
    const allowAnon = false;
    if (!allowAnon && route.name !== 'login') {
      return (
        <div>
          <window.Masthead route={route} go={go} session={null} isAdmin={false}/>
          <window.LoginPage go={go} route={route} onAuth={onAuth}/>
          <window.Footer stats={stats}/>
          <window.Tweaks theme={theme} setTheme={setTheme} visible={tweaksVisible}/>
        </div>
      );
    }
  }

  if (!data && user) {
    return (
      <div>
        <window.Masthead route={route} go={go} session={session} isAdmin={!!me?.isAdmin}/>
        <div className="section" style={{ padding:'80px 0', textAlign:'center', opacity:0.6 }}>
          {loadErr
            ? <div className="empty">Could not load the catalogue: {loadErr}</div>
            : <div className="empty">Fetching the catalogue…</div>}
        </div>
        <window.Footer stats={stats}/>
        <window.Tweaks theme={theme} setTheme={setTheme} visible={tweaksVisible}/>
      </div>
    );
  }

  let body = null;
  if (clerkReady && !user) {
    body = <window.LoginPage go={go} route={route} onAuth={onAuth}/>;
  } else if (data) {
    switch (route.name) {
      case 'home':
        body = <window.HomePage go={go} data={data}/>; break;
      case 'search':
        body = <window.SearchPage go={go} route={route} data={data}/>; break;
      case 'browse':
        if (!route.category) body = <BrowseLanding go={go} data={data}/>;
        else body = <window.SearchPage go={go} route={{...route, name:'search'}} data={data}/>;
        break;
      case 'book':
        body = <window.BookDetailPage go={go} route={route} data={data} session={session} onBorrow={onBorrow} wishlistToggle={wishlistToggle}/>;
        break;
      case 'login':
        body = <window.LoginPage go={go} route={route} onAuth={onAuth}/>; break;
      case 'account':
        body = <window.AccountPage go={go} data={data} session={session} onReturn={onReturn} onRenew={onRenew} wishlistToggle={wishlistToggle}/>;
        break;
      case 'confirm':
        body = <window.ConfirmPage go={go} data={data} route={route}/>; break;
      case 'librarian':
        body = <window.LibrarianPage go={go} data={data} isAdmin={!!me?.isAdmin} reload={reload}/>; break;
      default:
        body = <window.HomePage go={go} data={data}/>;
    }
  }

  return (
    <div>
      <window.Masthead route={route} go={go} session={session} isAdmin={!!me?.isAdmin}/>
      {body}
      <window.Footer stats={stats}/>
      <window.Tweaks theme={theme} setTheme={setTheme} visible={tweaksVisible}/>
    </div>
  );
}

function BrowseLanding({ go, data }){
  const cats = [
    { name:'Prototype History',    subs:['History','Lines & routes'] },
    { name:'Locomotives & Stock',  subs:['Locomotives','Rolling stock'] },
    { name:'Modelling & How-to',   subs:['Modelling','Electrics','Scenery','Layout design','Kitbuilding'] },
    { name:'Infrastructure',       subs:['Infrastructure','Signalling','Electrification','Industrial','Technical'] },
  ];
  return (
    <div className="section">
      <window.SectionHead eyebrow="Browse the library" title="By category"/>
      <div className="categories" style={{gridTemplateColumns:'repeat(2,1fr)'}}>
        {cats.map((c,i) => {
          const n = data.books.filter(b => c.subs.includes(b.subject)).length;
          return (
            <button key={c.name} className="cat-tile" onClick={() => go({name:'browse', category:c.name})}>
              <span className="num">No. {String(i+1).padStart(2,'0')}</span>
              <span className="name">{c.name}</span>
              <span className="count">{n} volumes · {c.subs.join(' · ')}</span>
            </button>
          );
        })}
      </div>
      <div className="spacer-xl"/>
      <window.SectionHead eyebrow="A–Z" title="Featured selections"/>
      <div className="shelf">
        {data.books.slice(0, 12).map(b => (
          <window.Bookplate key={b.id} book={b} onClick={() => go({name:'book', id:b.id})}/>
        ))}
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App/>);
