// SplitApp.jsx — the whole app: tabbed shell, flow stack, persistence. -> window.
// Storage namespace bumped to v3 for the fresh-start rework (only "You" by
// default, blank history, named guests). Old keys are simply ignored.
const LS_KEY = 'divvytab.v3';

function defaultSettings() {
  return { theme: 'pop', accent: 'default', font: 'default', fontScale: 1,
    currency: 'USD', defaultTip: 18, rounding: 'off', payApps: PAYMENT_APPS.map((a) => a.id) };
}
function freshFlow(settings) {
  return {
    screen: 'home', entry: 'manual', subtotalCents: 0,
    items: [], taxRate: 0, includeTax: false, merchant: '',
    tipPct: settings.defaultTip != null ? settings.defaultTip : 18,
    splitMode: 'even', partySize: 2,
    people: [{ id: 'p1', name: 'You', color: AVATAR_COLORS[0] }],
    customCents: {}, customItems: {}, paid: {}, requested: {},
  };
}

function loadPersisted() {
  try {
    const raw = localStorage.getItem(LS_KEY);
    if (raw) { const o = JSON.parse(raw); const s = { ...defaultSettings(), ...o.settings };
      if (s.rounding === 'total') s.rounding = 'nearest';
      return { settings: s, history: o.history || [] }; }
  } catch (e) {}
  return { settings: defaultSettings(), history: [] };
}

const TOP_TABS = ['home', 'history', 'settings'];
const FLOW_SCREENS = { home: HomeScreen, scan: ScanScreen, split: SplitScreen, assign: AssignScreen, tip: TipScreen, settle: SettleScreen };

function SplitApp({ width, height }) {
  const persisted = React.useRef(loadPersisted()).current;
  const [settings, setSettingsRaw] = React.useState(persisted.settings);
  const [history, setHistoryRaw] = React.useState(persisted.history);
  const [tab, setTab] = React.useState('home');         // which top tab we're on
  const [flow, setFlow] = React.useState(() => freshFlow(persisted.settings));
  const [toast, setToast] = React.useState(null);
  const toastT = React.useRef(0);

  // persist settings + history (namespaced; never touches other keys)
  React.useEffect(() => {
    try { localStorage.setItem(LS_KEY, JSON.stringify({ settings, history })); } catch (e) {}
  }, [settings, history]);

  const showToast = React.useCallback((msg, icon) => {
    setToast({ msg, icon }); clearTimeout(toastT.current);
    toastT.current = setTimeout(() => setToast(null), 2600);
  }, []);

  const setFlowState = React.useCallback((patch) => {
    setFlow((s) => ({ ...s, ...(typeof patch === 'function' ? patch(s) : patch) }));
  }, []);
  const setSettings = React.useCallback((next) => setSettingsRaw(next), []);
  const setHistory = React.useCallback((next) => setHistoryRaw(next), []);

  // start a brand-new manual bill (discards anything in progress)
  const clearBill = React.useCallback(() => { setFlow(freshFlow(settings)); setTab('home'); }, [settings]);

  // navigation: top tabs vs flow screens.
  //  • Going 'home' discards an unsaved RECEIPT (so it never bleeds into a
  //    manual bill); a manual bill is preserved so you can resume editing.
  const nav = React.useCallback((dest) => {
    if (dest === 'home') {
      setTab('home');
      setFlow((s) => (s.entry === 'receipt' ? freshFlow(settings) : { ...s, screen: 'home' }));
      return;
    }
    if (dest === 'history' || dest === 'settings') { setTab(dest); return; }
    setTab('home'); setFlowState({ screen: dest });   // flow screen
  }, [settings, setFlowState]);

  const currency = settings.currency || 'USD';
  const derived = computeDerived(flow, settings);

  // finish: snapshot to history, reset flow
  const onComplete = React.useCallback(() => {
    const d = computeDerived(flow, settings);
    const rec = {
      id: 'h' + Date.now(), merchant: flow.merchant || (flow.entry === 'receipt' ? 'Receipt' : 'Divvy'),
      date: new Date().toISOString(), mode: flow.splitMode, currency,
      subtotal: d.subtotal, tax: d.tax, tip: d.tip, grand: d.grand,
      people: d.rows.filter((r) => r.you || r.total > 0).map((r) => ({ name: r.you ? 'You' : r.name, you: !!r.you, color: r.color, total: r.total,
        request: r.you ? null : (flow.requested[r.id] ? { ...flow.requested[r.id], received: !!(flow.paid[r.id]) } : (flow.paid[r.id] ? { method: 'cash', at: new Date().toISOString(), received: true } : null)) })),
    };
    setHistoryRaw((h) => [rec, ...h]);
    setFlow(freshFlow(settings));
    setTab('history');
    showToast('Saved to history', <IconCheck s={18} />);
  }, [flow, settings, currency, showToast]);

  // theme from settings
  const dir = DIRECTIONS.find((d) => d.id === settings.theme) || DIRECTIONS[1];
  const theme = resolveTheme(dir, { accent: settings.accent, font: settings.font, fontScale: settings.fontScale });
  const vars = themeVars(theme);

  // which screen renders
  const isTop = (tab === 'home' && flow.screen === 'home') || tab === 'history' || tab === 'settings';
  let body;
  if (tab === 'history') body = <HistoryScreen history={history} setHistory={setHistory} currency={currency} nav={nav} />;
  else if (tab === 'settings') body = <SettingsScreen settings={settings} setSettings={setSettings} nav={nav} />;
  else {
    const Screen = FLOW_SCREENS[flow.screen] || HomeScreen;
    body = <Screen state={flow} set={setFlowState} derived={derived} currency={currency} nav={nav} theme={theme} toast={showToast} onComplete={onComplete} clearBill={clearBill} settings={settings} />;
  }
  const showNav = isTop;
  const navTab = tab === 'home' ? 'home' : tab;

  return (
    <div style={vars}>
      <PhoneShell theme={theme} width={width} height={height}>
        <div key={tab + ':' + flow.screen} className="ta-fade" style={{ flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column' }}>
          {body}
        </div>
        {showNav && <BottomNav tab={navTab} nav={nav} />}
        <Toast toast={toast} />
      </PhoneShell>
    </div>
  );
}

Object.assign(window, { SplitApp, defaultSettings, freshFlow });
