// TextiGreen v4 · app shell

const { useState: useSa4, useEffect: useEa4, useMemo: useMa4 } = React;

const DEFAULT_FORM = {
  composition: [{ fiber: 'Cotton (conventional)', fraction: 0.65 }, { fiber: 'Polyester (virgin PSF)', fraction: 0.35 }],
  stage: 'fiber',
  origin: 'Vietnam',
  dyeing: 'conventional',
  fabrication: 'weaving',
  boiler_fuel: 'natural_gas',
  base_geo: 'China_national',
};

function App() {
  const conn = useConnection();
  // The connection mode switcher / API settings are a DEVELOPER tool — hidden
  // for end users. Append ?dev to the URL (or set localStorage tg4.dev=1) to show it.
  const DEV = (() => {
    try {
      return new URLSearchParams(window.location.search).has('dev')
        || localStorage.getItem('tg4.dev') === '1';
    } catch (e) { return false; }
  })();
  const [settingsOpen, setSettingsOpen] = useSa4(false);
  const [guideOpen, setGuideOpen] = useSa4(false);
  const [form, setForm] = useSa4(() => {
    try { const s = localStorage.getItem('tg4.form'); if (s) return JSON.parse(s); } catch (e) {}
    return DEFAULT_FORM;
  });
  useEa4(() => { try { localStorage.setItem('tg4.form', JSON.stringify(form)); } catch (e) {} }, [form]);

  // catalogs (re-fetch when connection mode flips)
  const cat = useAsync(async () => {
    const [fibers, geos, processes, fuels] = await Promise.all([
      window.TGApi.fibers(), window.TGApi.geos(), window.TGApi.processes(), window.TGApi.fuels(),
    ]);
    return { fibers, geos, processes, fuels };
  }, [conn.usingLive]);
  useEa4(() => {
    const fibers = cat.data?.fibers || [];
    if (!fibers.length || !window.TGFiberCatalog?.resolveFiberValue) return;
    let changed = false;
    const composition = form.composition.map(c => {
      const fiber = window.TGFiberCatalog.resolveFiberValue(c.fiber, fibers);
      if (fiber !== c.fiber) changed = true;
      return { ...c, fiber };
    });
    if (changed) setForm({ ...form, composition });
  }, [cat.data?.fibers, JSON.stringify(form.composition)]);

  // estimate (debounced body)
  const debForm = useDebounced(form, 400);
  const est = useAsync(
    () => window.TGApi.estimate(sanitize(debForm)),
    [JSON.stringify(debForm), conn.usingLive]
  );

  return (
    <div style={{ minHeight: '100vh', background: 'var(--bg)', display: 'flex', flexDirection: 'column' }}>
      <header style={{ position: 'sticky', top: 0, zIndex: 40, background: 'var(--bg)', borderBottom: '1px solid var(--line)' }}>
        <div className="tg4-wrap" style={{ padding: '14px 20px', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12 }}>
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 12 }}>
            <Logo />
            <span style={{ fontSize: 11, color: 'var(--muted)', fontFamily: 'var(--mono)', letterSpacing: '0.04em' }} className="tg4-tagline">carbon pre-estimator</span>
            <a
              href="https://www.fjoratex.com"
              target="_blank"
              rel="noopener noreferrer"
              aria-label="FjoraTex official site (opens in new tab)"
              style={{ fontSize: 11, color: '#c4b0e8', fontFamily: 'var(--mono)', letterSpacing: '0.04em', textDecoration: 'none' }}
              onMouseEnter={e => { e.currentTarget.style.color = '#9575cd'; }}
              onMouseLeave={e => { e.currentTarget.style.color = '#c4b0e8'; }}
            >by FjoraTex ↗</a>
          </span>
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
            <button
              type="button"
              onClick={() => setGuideOpen(true)}
              style={{ padding: '4px 10px', border: '1px solid var(--line)', background: 'var(--bg)', color: 'var(--muted)', cursor: 'pointer', fontSize: 11, fontFamily: 'var(--mono)', letterSpacing: '0.03em' }}
              onMouseEnter={e => { e.currentTarget.style.color = 'var(--fg)'; e.currentTarget.style.borderColor = 'var(--fg)'; }}
              onMouseLeave={e => { e.currentTarget.style.color = 'var(--muted)'; e.currentTarget.style.borderColor = 'var(--line)'; }}
            >How to use</button>
            {DEV
              ? <ConnectionPill conn={conn} onClick={() => setSettingsOpen(true)} />
              : (conn.status === 'offline'
                  ? <OfflineTag label="demo data" danger />
                  : null)}
          </span>
        </div>
      </header>

      <main className="tg4-wrap" style={{ flex: 1, padding: '24px 20px 110px', width: '100%' }}>
        <div className="tg4-grid">
          {/* form panel */}
          <div className="tg4-form">
            <div style={{ position: 'sticky', top: 78 }}>
              {cat.loading && !cat.data ? (
                <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
                  <Skeleton height={40} /><Skeleton height={120} /><Skeleton height={80} />
                </div>
              ) : cat.error ? (
                <WarningBar tone="strong">Failed to load catalogs: {cat.error}</WarningBar>
              ) : cat.data ? (
                <EstimatorForm catalogs={cat.data} value={form} onChange={setForm} />
              ) : null}
            </div>
          </div>

          {/* result hero */}
          <div className="tg4-result">
            <ResultView result={est.data} loading={est.loading} error={est.error} />
          </div>
        </div>
      </main>

      {/* disclaimer — always visible */}
      <footer style={{ position: 'fixed', bottom: 0, left: 0, right: 0, background: 'var(--surface)', borderTop: '1px solid var(--line)', padding: '10px 20px', zIndex: 30 }}>
        <div className="tg4-wrap" style={{ fontSize: 11, color: 'var(--muted)', lineHeight: 1.5 }}>
          <strong style={{ color: 'var(--fg)' }}>Disclaimer · </strong>
          {est.data?.disclaimer || 'Pre-estimate for design/sourcing communication — NOT a certified LCA, carbon-neutral, or zero-carbon claim.'}
          {' · Built by '}
          <a
            href="https://www.fjoratex.com"
            target="_blank"
            rel="noopener noreferrer"
            aria-label="FjoraTex official site (opens in new tab)"
            style={{ color: '#c4b0e8', textDecoration: 'none' }}
            onMouseEnter={e => { e.currentTarget.style.color = '#9575cd'; }}
            onMouseLeave={e => { e.currentTarget.style.color = '#c4b0e8'; }}
          >FjoraTex</a>
          {' · '}
          <a
            href="https://www.fjoratex.com"
            target="_blank"
            rel="noopener noreferrer"
            aria-label="FjoraTex official site (opens in new tab)"
            style={{ color: 'var(--muted)', textDecoration: 'none' }}
            onMouseEnter={e => { e.currentTarget.style.color = 'var(--fg)'; }}
            onMouseLeave={e => { e.currentTarget.style.color = 'var(--muted)'; }}
          >www.fjoratex.com ↗</a>
        </div>
      </footer>

      {settingsOpen && <SettingsPanel conn={conn} onClose={() => setSettingsOpen(false)} />}
      {guideOpen && <GuidePanel onClose={() => setGuideOpen(false)} />}
    </div>
  );
}

// strip empty optionals + ensure composition fractions
function sanitize(f) {
  const composition = f.composition.filter(c => c.fiber && c.fraction > 0).map(c => ({ fiber: c.fiber, fraction: c.fraction }));
  const body = { composition, stage: f.stage, base_geo: f.base_geo || 'China_national' };
  if (f.origin) body.origin = f.origin;
  if (f.dyeing) body.dyeing = f.dyeing;
  if (f.fabrication) body.fabrication = f.fabrication;
  if (f.boiler_fuel) body.boiler_fuel = f.boiler_fuel;
  return body;
}

window.App = App;
