// Desktop SaaS shell for the TeachCue Studio app. Mounted by studio.html.
//
// Why this exists: the original React app shipped inside an iOS-frame demo
// (TeachCue-iOS.html → IOSDevice wrapper). That's a marketing visualization
// of the unpublished iOS app, NOT the actual web product. The Studio shell
// is the real desktop SaaS surface — same React screens, no phone frame,
// plus an /api/me-backed plan badge and a Stripe-aware soft paywall.

const { useState: uSh, useEffect: uEh } = React;

// ─────────────────────────────────────────────────────────────
// Seed data — mirrors the iOS demo. Real persistence lives behind
// /api/decks (already implemented server-side). The Studio shell uses
// local state for v1; deck sync wiring is a separate change.
// ─────────────────────────────────────────────────────────────

const initialSlides = [
  { id:1, text:'Welcome — record your first tutorial in TeachCue Studio.', explanation:'', lang:'en', hasImage:false },
  { id:2, text:'Type your script in the prepare step.', explanation:'', lang:'en', hasImage:false },
  { id:3, text:'Hit record. Smart-follow will auto-scroll the teleprompter.', explanation:'', lang:'en', hasImage:false },
];

const initialProjects = [
  { id:1, title:'Untitled project', slides:3, time:'now', status:'draft', lang:'EN',
    caption:'Welcome', gradient:'linear-gradient(150deg, #2a3b47 0%, #0f1519 100%)' },
];

// ─────────────────────────────────────────────────────────────
// Plan tier — pulled from /api/me; falls back to 'free' on 401 so the
// app still works for signed-out visitors (matching the marketing
// promise of a Free tier without a card).
// ─────────────────────────────────────────────────────────────

function usePlanTier() {
  const [plan, setPlan] = uSh('loading'); // loading | free | plus | pro
  const [user, setUser] = uSh(null);

  uEh(() => {
    let cancelled = false;
    (async () => {
      try {
        const r = await fetch('/api/me', { credentials: 'include' });
        if (cancelled) return;
        if (r.ok) {
          const data = await r.json();
          const p = (data.user?.plan || 'free').toLowerCase();
          setPlan(p === 'plus' || p === 'pro' ? p : 'free');
          setUser(data.user || null);
        } else {
          // 401 → guest visitor, treat as free tier so the UI is usable
          setPlan('free');
          setUser(null);
        }
      } catch {
        if (!cancelled) { setPlan('free'); setUser(null); }
      }
    })();
    return () => { cancelled = true; };
  }, []);

  return { plan, user };
}

// ─────────────────────────────────────────────────────────────
// Studio root — orchestrates screen routing + plan-aware state.
// ─────────────────────────────────────────────────────────────

function StudioApp() {
  // Lazy-init from the URL hash so a direct visit to /studio#/record
  // doesn't briefly flash the Home screen before the hashchange effect
  // catches up. The mount-time `useEffect` below also reads the hash
  // for in-app navigation, but the first paint matters most.
  const [screen, setScreen] = uSh(() => {
    if (typeof location === 'undefined') return 'home';
    const h = location.hash.replace(/^#\/?/, '');
    return ['home','prepare','record','edit','share'].includes(h) ? h : 'home';
  });
  const { plan, user } = usePlanTier();

  const [state, setState] = uSh({
    title: 'Untitled project',
    slides: initialSlides,
    overlayConfigs: {},
    aspect: '16:9',   // desktop default — landscape matches Loom/Riverside/Zoom expectations. Portrait remains a project-level option.
    composition: 'cameraOnly',
    projects: initialProjects,
    recording: null,
  });

  // ── Persist screen in URL hash so refresh keeps you where you were.
  //    React listens to hashchange so the side-rail "New" button (which is
  //    plain DOM) can drive navigation. ──
  uEh(() => {
    const apply = () => {
      const h = location.hash.replace(/^#\/?/, '');
      if (h && ['home','prepare','record','edit','share'].includes(h)) setScreen(h);
    };
    apply();
    window.addEventListener('hashchange', apply);
    return () => window.removeEventListener('hashchange', apply);
  }, []);
  uEh(() => {
    location.hash = '#/' + screen;
    const canvas = document.getElementById('canvas');
    if (canvas) {
      canvas.setAttribute('data-screen', screen);
      // Warm-cream background for non-recording screens.
      canvas.classList.toggle('warm', screen === 'home' || screen === 'prepare' || screen === 'share');
    }
    // Crumb in the top nav reflects the active step
    const crumb = document.getElementById('crumb');
    if (crumb) crumb.textContent = 'Studio · ' + ({
      home: 'Projects', prepare: 'Prepare', record: 'Record', edit: 'Edit', share: 'Export',
    }[screen] || 'Projects');
    // Stage hint changes per screen so the phone-shaped canvas reads
    // intentional ("preview", not "mobile-only"). Hidden on /record
    // because the desktop record view has its own inline controls and
    // labels — no extra hint needed.
    const hint = document.getElementById('hint-text');
    const hintWrap = document.querySelector('.stage-hint');
    const hintCopy = {
      home: 'Open a project or start a new tutorial',
      prepare: 'Draft your slides — record when you\'re ready',
      record: '',
      edit: 'Preview, scrub, and refine before export',
      share: 'Pick a quality and destination — captions exported alongside',
    }[screen] || '';
    if (hint) hint.textContent = hintCopy;
    if (hintWrap) hintWrap.style.display = hintCopy ? '' : 'none';
  }, [screen]);

  // ── Mirror plan into the chrome (top badge + sidebar footer) ──
  uEh(() => {
    const root = document.getElementById('studio-root');
    if (root) root.setAttribute('data-plan', plan);
    const label = document.getElementById('plan-label');
    if (label) label.textContent = plan === 'loading' ? '…' : plan;
    const badge = document.getElementById('plan-badge');
    if (badge) {
      badge.dataset.plan = plan;
      badge.classList.toggle('plan-plus', plan === 'plus');
      badge.classList.toggle('plan-pro',  plan === 'pro');
    }
    const foot = document.getElementById('side-foot');
    const title = document.getElementById('side-plan-title');
    const note  = document.getElementById('side-plan-note');
    const cta   = document.getElementById('side-cta');
    if (foot) foot.classList.toggle('free', plan === 'free');
    if (title) title.textContent = plan === 'loading' ? 'Loading…' : ({
      free: 'Free', plus: 'Plus', pro: 'Pro',
    }[plan] || 'Free');
    if (note) note.textContent = ({
      free: '3 projects · 720p export · watermark',
      plus: 'Unlimited · 1080p · no watermark',
      pro:  'Everything · 4K · custom fonts',
    }[plan] || '');
    if (cta) {
      cta.style.display = plan === 'free' ? 'inline-flex' : 'none';
    }
  }, [plan]);

  // ── Render the sidebar project list from local state. Real deck-sync
  //    via /api/decks lands as a separate change. ──
  uEh(() => {
    const mount = document.getElementById('side-projects');
    if (!mount) return;
    const list = (state.projects || []).slice(0, 6);
    mount.innerHTML = '';
    list.forEach((p, i) => {
      const btn = document.createElement('button');
      btn.className = 'side-proj' + (i === 0 ? ' active' : '');
      btn.innerHTML = `
        <span class="thumb" style="background:${p.gradient || 'var(--rule-2)'}"></span>
        <span class="meta">
          <span class="t"></span>
          <span class="s"></span>
        </span>
        <span class="tag">${p.lang || 'EN'}</span>
      `;
      // textContent (not innerHTML) prevents script-injection on user-typed titles.
      btn.querySelector('.t').textContent = p.title || 'Untitled';
      btn.querySelector('.s').textContent = `${p.slides || 0} slides · ${p.time || 'now'}`;
      btn.addEventListener('click', () => setScreen('home'));
      mount.appendChild(btn);
    });
  }, [state.projects, screen]);

  // ── "+ New" button in sidebar — outside React, drive via hashchange. ──
  uEh(() => {
    const btn = document.getElementById('side-new-btn');
    if (!btn) return;
    const handler = () => setScreen('prepare');
    btn.addEventListener('click', handler);
    return () => btn.removeEventListener('click', handler);
  }, []);

  const set = (patch) => setState(s => ({ ...s, ...patch }));
  const nav = {
    go: (s) => setScreen(s),
    openTweaks: () => {},      // no design tweaks panel in the SaaS shell
  };

  // ── Plan-aware feature gating, passed down via state ──
  // Free → 720p, watermark, 9:16 only, max 3 projects, max 5 slides per project
  // Plus → 1080p, no watermark, all aspect ratios, unlimited projects/slides
  // Pro  → adds 4K + batch export + custom fonts
  const planLimits = {
    loading: { maxProjects: Infinity, maxSlides: Infinity, qualities: ['720p','1080p','4k'], watermark: false, aspectRatios: ['9:16','16:9','1:1'] },
    free:    { maxProjects: 3,        maxSlides: 5,        qualities: ['720p'],               watermark: true,  aspectRatios: ['9:16'] },
    plus:    { maxProjects: Infinity, maxSlides: Infinity, qualities: ['720p','1080p'],      watermark: false, aspectRatios: ['9:16','16:9','1:1'] },
    pro:     { maxProjects: Infinity, maxSlides: Infinity, qualities: ['720p','1080p','4k'], watermark: false, aspectRatios: ['9:16','16:9','1:1'] },
  };
  // Expose on state so screen-* modules can read it. Backwards-compatible:
  // existing screens that don't check plan keep working unchanged.
  const stateWithPlan = { ...state, plan, planLimits: planLimits[plan] || planLimits.free, user };

  // Use the desktop-native StudioRecord for the record screen on the
  // SaaS surface. The phone-shaped ScreenRecord stays available for the
  // iOS-frame demo (TeachCue-iOS.html).
  const screens = {
    home: <ScreenHome state={stateWithPlan} nav={nav}/>,
    prepare: <ScreenPrepare state={stateWithPlan} set={set} nav={nav}/>,
    record: window.StudioRecord
      ? <StudioRecord state={stateWithPlan} set={set} nav={nav}/>
      : <ScreenRecord state={stateWithPlan} set={set} nav={nav}/>,
    edit: <ScreenEdit state={stateWithPlan} set={set} nav={nav}/>,
    share: <ScreenShare state={stateWithPlan} set={set} nav={nav}/>,
  };

  return (
    <div data-screen-label={screen} style={{height:'100%', position:'relative', overflow:'hidden'}}>
      {screens[screen]}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Mount — App root + AccountWidget mount separately so the widget
// lives in the page chrome, not inside the recording canvas.
// ─────────────────────────────────────────────────────────────

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

// AccountWidget is defined in auth.jsx; mount only if it loaded.
if (typeof AccountWidget === 'function') {
  const acctMount = document.getElementById('account-mount');
  if (acctMount) {
    ReactDOM.createRoot(acctMount).render(<AccountWidget />);
  }
}
