/* ─────────────────────────────────────────────────────────────
   LEKHA · landing.jsx · public landing page
   Hero, product mockups, invite-only framing. Wraps the sign-in
   card, which is passed in from auth-gate.jsx.

   PUBLIC ASSET (worker/lib/asset-gate.js allowlist). It therefore
   carries NO real data. Every figure in the mockups below is
   invented and labelled as such — a landing page that showed a
   real holding would leak a portfolio to anyone who loaded the
   site unauthenticated.

   Mockups are DOM + inline SVG, never screenshots. Three reasons:
   the CSP has no img-src for an external host, screenshots of a
   private book cannot be published, and vector mockups stay sharp
   and re-theme themselves from tokens.css.

   Wrapped in an IIFE: this file is loaded by a plain
   <script type="text/babel"> tag, not through load-gated.js, so
   top-level declarations would land on window and collide.
   ───────────────────────────────────────────────────────────── */
(function () {
  const { useState, useEffect } = React;

  // Inline styles beat media queries, so breakpoints have to be state.
  // Mirrors the approach in runtime/responsive.js, reimplemented here
  // because that file is not on the public allowlist and this page must
  // render before any authentication happens.
  function useViewport() {
    const get = () => (typeof window === 'undefined' ? 1280 : window.innerWidth);
    const [width, setWidth] = useState(get);
    useEffect(() => {
      let frame = null;
      const onResize = () => {
        if (frame) cancelAnimationFrame(frame);
        frame = requestAnimationFrame(() => setWidth(get()));
      };
      window.addEventListener('resize', onResize, { passive: true });
      return () => {
        window.removeEventListener('resize', onResize);
        if (frame) cancelAnimationFrame(frame);
      };
    }, []);
    return { width, narrow: width < 900, tight: width < 620 };
  }

  /**
   * The document body carries `overflow: hidden` (index.html) because the
   * signed-in shell scrolls INTERNALLY — `.app-layout` is height:100vh and
   * `.main-area` does the scrolling. The landing page is the opposite: an
   * ordinary long document that must scroll the body. Without this the page
   * simply froze below the fold, with no way to reach the mockups or the
   * invite-only section.
   *
   * Scoped to while the landing page is mounted, and restored on unmount, so
   * signing in returns the shell to its own scroll model.
   */
  function useBodyScroll() {
    useEffect(() => {
      const body = document.body;
      const html = document.documentElement;
      const prev = { body: body.style.overflow, html: html.style.height, bodyH: body.style.height };
      // 'visible', not 'auto': overflow:auto turns the body itself into a
      // scroll box, which competes with the viewport for who is scrolling and
      // left the last ~450px (the footer) unreachable. 'visible' restores
      // ordinary document scrolling.
      body.style.overflow = 'visible';
      // height:100% on html/body/#root pins them to the viewport; the landing
      // page needs to grow past it.
      html.style.height = 'auto';
      body.style.height = 'auto';
      return () => {
        body.style.overflow = prev.body;
        html.style.height = prev.html;
        body.style.height = prev.bodyH;
      };
    }, []);
  }

  const INR = (n) => `₹${n.toLocaleString('en-IN')}`;

  /* ── Primitives ─────────────────────────────────────────── */

  function Eyebrow({ children, tone }) {
    return (
      <span style={{
        display: 'inline-flex', alignItems: 'center', gap: 8,
        fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.14em',
        textTransform: 'uppercase', color: tone || 'var(--text-dim)',
      }}>{children}</span>
    );
  }

  function InviteBadge() {
    return (
      <span style={{
        display: 'inline-flex', alignItems: 'center', gap: 8,
        padding: '6px 14px', borderRadius: 'var(--r-pill)',
        border: '1px solid rgba(232,160,32,0.45)', background: 'rgba(232,160,32,0.10)',
        fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.12em',
        textTransform: 'uppercase', color: '#8A5B00', whiteSpace: 'nowrap',
      }}>
        <span style={{
          width: 6, height: 6, borderRadius: '50%',
          background: 'var(--madhubani-gold)', flexShrink: 0,
        }} />
        Invite-only preview
      </span>
    );
  }

  /** Chrome around a mockup so it reads as a screen, not a table on the page. */
  function ScreenFrame({ title, children, accent }) {
    return (
      <div style={{
        background: 'var(--surface)', border: '1px solid var(--border)',
        borderRadius: 'var(--r-card)', overflow: 'hidden',
        boxShadow: '0 1px 2px rgba(28,28,28,0.04), 0 12px 32px -12px rgba(28,28,28,0.16)',
        display: 'flex', flexDirection: 'column', height: '100%',
      }}>
        <div style={{
          display: 'flex', alignItems: 'center', gap: 10, padding: '10px 14px',
          borderBottom: '1px solid var(--border)', background: 'var(--surface-alt)',
        }}>
          <span style={{ display: 'flex', gap: 5 }} aria-hidden="true">
            {['#E0655A', '#E8B44A', '#7FB88A'].map((c) => (
              <span key={c} style={{ width: 8, height: 8, borderRadius: '50%', background: c, opacity: 0.75 }} />
            ))}
          </span>
          <span style={{
            fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.08em',
            textTransform: 'uppercase', color: 'var(--text-muted)',
          }}>{title}</span>
          {accent && (
            <span style={{
              marginLeft: 'auto', fontFamily: 'var(--font-mono)', fontSize: 11,
              color: accent.tone, fontWeight: 600,
            }}>{accent.label}</span>
          )}
        </div>
        <div style={{ padding: 14, flex: 1 }}>{children}</div>
      </div>
    );
  }

  const Row = ({ cells, bold, tone, top }) => (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 8, padding: '7px 0',
      borderTop: top ? '1px solid var(--border)' : 'none',
      fontFamily: 'var(--font-body)', fontSize: 12,
      color: tone || (bold ? 'var(--text)' : 'var(--text-muted)'),
      fontWeight: bold ? 600 : 400,
    }}>
      {cells.map((c, i) => (
        <span key={i} style={{
          flex: c.flex || 1, textAlign: c.right ? 'right' : 'left',
          fontFamily: c.mono ? 'var(--font-mono)' : 'inherit',
          color: c.tone || 'inherit', whiteSpace: 'nowrap',
          overflow: 'hidden', textOverflow: 'ellipsis',
        }}>{c.v}</span>
      ))}
    </div>
  );

  const Head = ({ cells }) => (
    <div style={{
      display: 'flex', gap: 8, paddingBottom: 6, borderBottom: '1px solid var(--border-mid)',
      fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.06em',
      textTransform: 'uppercase', color: 'var(--text-dim)',
    }}>
      {cells.map((c, i) => (
        <span key={i} style={{ flex: c.flex || 1, textAlign: c.right ? 'right' : 'left' }}>{c.v}</span>
      ))}
    </div>
  );

  /* ── Mock screens ───────────────────────────────────────── */

  function MockHoldings({ tight }) {
    const rows = [
      ['HDFC Bank', 'Equity', 482300, '14.2%'],
      ['Parag Parikh Flexi Cap', 'Mutual fund', 615400, '18.7%'],
      ['SGB 2031 Sr-III', 'Sov. gold bond', 274900, '11.3%'],
      ['NPS Tier I', 'NPS', 308600, '12.1%'],
      ['SBI PPF', 'PPF', 541200, '7.1%'],
    ];
    return (
      <ScreenFrame title="Holdings & XIRR" accent={{ label: '▲ 13.4% XIRR', tone: 'var(--paddy-green)' }}>
        <Head cells={[
          { v: 'Holding', flex: tight ? 1.9 : 2.2 },
          ...(tight ? [] : [{ v: 'Class', flex: 1.4 }]),
          { v: 'Value', right: true, flex: 1.25 },
          { v: 'XIRR', right: true, flex: 0.75 },
        ]} />
        {rows.map(([n, c, v, x]) => (
          <Row key={n} cells={[
            { v: n, flex: tight ? 1.9 : 2.2, tone: 'var(--text)' },
            ...(tight ? [] : [{ v: c, flex: 1.4 }]),
            { v: INR(v), right: true, flex: 1.25, mono: true },
            { v: x, right: true, flex: 0.75, mono: true, tone: 'var(--paddy-green)' },
          ]} />
        ))}
        <Row top bold cells={[
          { v: 'Book total', flex: tight ? 1.9 : 2.2 },
          ...(tight ? [] : [{ v: '', flex: 1.4 }]),
          { v: INR(2222400), right: true, flex: 1.25, mono: true },
          { v: '13.4%', right: true, flex: 0.75, mono: true, tone: 'var(--paddy-green)' },
        ]} />
      </ScreenFrame>
    );
  }

  function MockCapitalGains({ tight }) {
    return (
      <ScreenFrame title="Capital gains · FY 2025-26" accent={{ label: 'AY 2026-27', tone: 'var(--text-dim)' }}>
        <Head cells={[{ v: 'Head', flex: 2 }, { v: 'Gain', right: true }, { v: 'Tax', right: true, flex: 0.8 }]} />
        <Row cells={[
          { v: tight ? 's.111A @ 20%' : 'Short-term · s.111A @ 20%', flex: 2, tone: 'var(--text)' },
          { v: INR(92000), right: true, mono: true },
          { v: INR(18400), right: true, flex: 0.8, mono: true },
        ]} />
        <Row cells={[
          { v: tight ? 's.112A @ 12.5%' : 'Long-term · s.112A @ 12.5%', flex: 2, tone: 'var(--text)' },
          { v: INR(196000), right: true, mono: true },
          { v: INR(8875), right: true, flex: 0.8, mono: true },
        ]} />
        {/* The ₹1.25L s.112A exemption applies to the AGGREGATE, not per
            trade — showing it as its own line is how the app avoids
            implying otherwise. */}
        <Row cells={[
          { v: tight ? '↳ exempt threshold' : '↳ exempt threshold (aggregate)', flex: 2 },
          { v: `− ${INR(125000)}`, right: true, mono: true, tone: 'var(--paddy-green)' },
          { v: '', right: true, flex: 0.8 },
        ]} />
        <Row cells={[
          { v: 'Debt MF · s.50AA at slab', flex: 2, tone: 'var(--text)' },
          { v: INR(41000), right: true, mono: true },
          { v: INR(12300), right: true, flex: 0.8, mono: true },
        ]} />
        <div style={{
          marginTop: 10, padding: '8px 10px', borderRadius: 'var(--r-sm)',
          background: 'rgba(232,160,32,0.10)', border: '1px solid rgba(232,160,32,0.3)',
          fontFamily: 'var(--font-body)', fontSize: 11, color: '#7A5200', lineHeight: 1.5,
        }}>
          <strong>1 open item.</strong> SGB redeemed at maturity — exempt under
          s.47(viic), or a sale? Lekha shows both and asks; it never picks a
          side on an arguable question.
        </div>
      </ScreenFrame>
    );
  }

  function MockIncome({ tight }) {
    const rows = [
      ['7.26% GS 2033', 'Coupon', '12 Nov', 18150, 'var(--kahalgaon-blue)'],
      ['ICICI FD · 7.1%', 'Interest accrued', '31 Mar', 9480, 'var(--tussar-silk)'],
      ['ITC Ltd', 'Dividend', '04 Aug', 3240, 'var(--paddy-green)'],
      ['SBI PPF', 'Interest credited', '31 Mar', 38420, 'var(--madhubani-gold)'],
    ];
    return (
      <ScreenFrame title="Income & due dates" accent={{ label: '2 due in 30d', tone: 'var(--mithila-vermillion)' }}>
        <Head cells={[
          { v: 'Source', flex: 2 },
          ...(tight ? [] : [{ v: 'Type', flex: 1.5 }]),
          { v: 'Date', flex: 0.9 },
          { v: 'Amount', right: true, flex: 1.15 },
        ]} />
        {rows.map(([n, t, d, a, c]) => (
          <Row key={n} cells={[
            { v: <span><span style={{ display: 'inline-block', width: 6, height: 6, borderRadius: '50%', background: c, marginRight: 7 }} />{n}</span>, flex: 2, tone: 'var(--text)' },
            ...(tight ? [] : [{ v: t, flex: 1.5 }]),
            { v: d, flex: 0.9, mono: true },
            { v: INR(a), right: true, flex: 1.15, mono: true },
          ]} />
        ))}
        <Row top bold cells={[
          { v: 'FY income', flex: 2 },
          ...(tight ? [] : [{ v: '', flex: 1.5 }]),
          { v: '', flex: 0.9 },
          { v: INR(69290), right: true, flex: 1.15, mono: true },
        ]} />
        <div style={{
          marginTop: 8, fontFamily: 'var(--font-mono)', fontSize: 10,
          color: 'var(--text-dim)', lineHeight: 1.6,
        }}>
          NEXT · PPF minimum by 05 Apr · FD matures 22 Jan
        </div>
      </ScreenFrame>
    );
  }

  function MockAllocation() {
    const slices = [
      ['Equity', 38, 'var(--kahalgaon-blue)'],
      ['Mutual funds', 26, 'var(--shravan-teal)'],
      ['Fixed income', 21, 'var(--tussar-silk)'],
      ['Gold / SGB', 9, 'var(--madhubani-gold)'],
      ['NPS', 6, 'var(--paddy-green)'],
    ];
    const R = 52, C = 2 * Math.PI * R;
    let offset = 0;
    return (
      <ScreenFrame title="Annual asset report" accent={{ label: '31 Mar 2026', tone: 'var(--text-dim)' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 18, flexWrap: 'wrap' }}>
          <svg width="132" height="132" viewBox="0 0 132 132" role="img"
            aria-label="Illustrative allocation: equity 38%, mutual funds 26%, fixed income 21%, gold 9%, NPS 6%">
            <g transform="rotate(-90 66 66)">
              {slices.map(([label, pct, colour]) => {
                const len = (pct / 100) * C;
                const el = (
                  <circle key={label} cx="66" cy="66" r={R} fill="none"
                    stroke={colour} strokeWidth="17"
                    strokeDasharray={`${len} ${C - len}`}
                    strokeDashoffset={-offset} />
                );
                offset += len;
                return el;
              })}
            </g>
            <text x="66" y="62" textAnchor="middle"
              style={{ fontFamily: 'var(--font-mono)', fontSize: 15, fontWeight: 700, fill: 'var(--text)' }}>₹22.2L</text>
            <text x="66" y="77" textAnchor="middle"
              style={{ fontFamily: 'var(--font-mono)', fontSize: 9.5, letterSpacing: '0.08em', fill: 'var(--text-dim)' }}>NET WORTH</text>
          </svg>
          <div style={{ flex: 1, minWidth: 140 }}>
            {slices.map(([label, pct, colour]) => (
              <div key={label} style={{
                display: 'flex', alignItems: 'center', gap: 8, padding: '4px 0',
                fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--text-muted)',
              }}>
                <span style={{ width: 9, height: 9, borderRadius: 2, background: colour, flexShrink: 0 }} />
                <span style={{ flex: 1 }}>{label}</span>
                <span style={{ fontFamily: 'var(--font-mono)', color: 'var(--text)' }}>{pct}%</span>
              </div>
            ))}
          </div>
        </div>
      </ScreenFrame>
    );
  }

  /* ── Page ───────────────────────────────────────────────── */

  const CAPABILITIES = [
    ['Every asset in one book', 'Equities, mutual funds (equity and debt), PPF, EPF, NPS Tier I & II, traded bonds, fixed deposits and sovereign gold bonds — held together, not in six spreadsheets.'],
    ['Statements in, lots out', 'Import from ICICI Direct, Zerodha Kite, Coin and IBKR. FIFO tax lots are replayed from your own trade history, so cost basis is derived, never guessed.'],
    ['Indian tax, stated honestly', 'Capital gains under s.111A, s.112A, s.112 and s.50AA, with 31-Jan-2018 grandfathering. Where the law is arguable, Lekha shows both readings and flags an open item.'],
    ['Returns you can defend', 'XIRR from dated cashflows, with the absolute return beside it — because annualising a three-week gain flatters it. Unpriced positions suppress the number rather than skew it.'],
    ['Income and due dates', 'Coupons, dividends, FD and PPF interest across the financial year, plus what falls due next — maturities, contribution deadlines, reset dates.'],
    ['Yours, on your device', 'Statements are parsed in the browser and discarded. What syncs is encrypted before it leaves, under a key the server never holds.'],
  ];

  function LandingPage({ children }) {
    const { narrow, tight } = useViewport();
    useBodyScroll();

    return (
      <div style={{ minHeight: '100%', height: 'auto', background: 'var(--bg)', color: 'var(--text)' }}>
        {/* Warm wash behind the fold; keeps the light theme from reading flat. */}
        <div style={{
          background: 'linear-gradient(168deg, #FFFDF9 0%, var(--bg) 46%, #F3EDE3 100%)',
          borderBottom: '1px solid var(--border)',
        }}>
          <div style={{
            maxWidth: 1180, margin: '0 auto', padding: tight ? '28px 20px 44px' : '52px 32px 68px',
            display: 'grid', gap: narrow ? 40 : 56,
            gridTemplateColumns: narrow ? '1fr' : 'minmax(0,1.15fr) minmax(360px,0.85fr)',
            alignItems: 'center',
          }}>
            <div>
              <InviteBadge />

              <h1 style={{
                fontFamily: 'var(--font-display)', fontWeight: 700,
                fontSize: 'clamp(2.6rem, 6vw, 4.2rem)', lineHeight: 1.04,
                color: 'var(--primary)', margin: '22px 0 0', letterSpacing: '-0.02em',
              }}>
                Lekha
                <span style={{
                  fontFamily: 'var(--font-script)', fontWeight: 400,
                  fontSize: '0.42em', color: 'var(--madhubani-gold)',
                  marginLeft: 14, verticalAlign: 'super', letterSpacing: 0,
                }}>लेखा</span>
              </h1>

              <p style={{
                fontFamily: 'var(--font-display)', fontWeight: 600,
                fontSize: 'clamp(1.15rem, 2.4vw, 1.6rem)', lineHeight: 1.35,
                color: 'var(--text)', margin: '16px 0 0', maxWidth: '20ch',
              }}>
                One honest account of everything you own.
              </p>

              <p style={{
                fontFamily: 'var(--font-body)', fontSize: 'clamp(0.95rem, 1.4vw, 1.05rem)',
                lineHeight: 1.75, color: 'var(--text-muted)', margin: '18px 0 0', maxWidth: '54ch',
              }}>
                A local-first wealth console for Indian portfolios. Import your broker
                and scheme statements, and Lekha rebuilds the tax lots, capital gains,
                income and XIRR behind them — showing its working, and telling you
                plainly when a number cannot be trusted yet.
              </p>

              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, marginTop: 26 }}>
                {['Local-first', 'Zero-knowledge sync', 'Two-factor', 'No ads, no data sale'].map((t) => (
                  <span key={t} style={{
                    padding: '6px 12px', borderRadius: 'var(--r-pill)',
                    border: '1px solid var(--border-mid)', background: 'var(--surface)',
                    fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.06em',
                    textTransform: 'uppercase', color: 'var(--text-muted)',
                  }}>{t}</span>
                ))}
              </div>
            </div>

            {/* The sign-in card, passed in by auth-gate.jsx. The landing page
                deliberately owns no auth logic — it only gives it a home. */}
            <div style={{ width: '100%', justifySelf: narrow ? 'stretch' : 'end', maxWidth: narrow ? 520 : 460 }}>
              {children}
            </div>
          </div>
        </div>

        {/* ── Mockups ── */}
        <div style={{ maxWidth: 1180, margin: '0 auto', padding: tight ? '48px 20px' : '72px 32px' }}>
          <Eyebrow>Inside the console</Eyebrow>
          <h2 style={{
            fontFamily: 'var(--font-display)', fontWeight: 700,
            fontSize: 'clamp(1.6rem, 3.2vw, 2.4rem)', lineHeight: 1.2,
            color: 'var(--primary)', margin: '10px 0 8px', letterSpacing: '-0.01em',
          }}>
            Five views over one book
          </h2>
          <p style={{
            fontFamily: 'var(--font-body)', fontSize: 15, lineHeight: 1.7,
            color: 'var(--text-muted)', maxWidth: '62ch', margin: '0 0 32px',
          }}>
            Holdings and XIRR, capital gains, income, due dates, and the annual
            asset report — each derived from the same imported statements, so
            they cannot disagree with one another.
          </p>

          <div style={{
            display: 'grid', gap: 22,
            gridTemplateColumns: narrow ? '1fr' : 'repeat(2, minmax(0, 1fr))',
          }}>
            <MockHoldings tight={tight} />
            <MockCapitalGains tight={tight} />
            <MockIncome tight={tight} />
            <MockAllocation />
          </div>

          {/* Saying this once, clearly, is the difference between a mockup and
              a misrepresentation. */}
          <p style={{
            fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.06em',
            color: 'var(--text-dim)', marginTop: 18, textAlign: 'center',
          }}>
            Illustrative figures — not a real portfolio.
          </p>
        </div>

        {/* ── Capabilities ── */}
        <div style={{ background: 'var(--surface-alt)', borderTop: '1px solid var(--border)', borderBottom: '1px solid var(--border)' }}>
          <div style={{ maxWidth: 1180, margin: '0 auto', padding: tight ? '48px 20px' : '68px 32px' }}>
            <Eyebrow>What it does</Eyebrow>
            <div style={{
              display: 'grid', gap: tight ? 24 : 30, marginTop: 26,
              gridTemplateColumns: narrow ? '1fr' : 'repeat(auto-fit, minmax(300px, 1fr))',
            }}>
              {CAPABILITIES.map(([title, body]) => (
                <div key={title}>
                  <h3 style={{
                    fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 16,
                    color: 'var(--primary)', margin: '0 0 8px',
                  }}>{title}</h3>
                  <p style={{
                    fontFamily: 'var(--font-body)', fontSize: 13.5, lineHeight: 1.75,
                    color: 'var(--text-muted)', margin: 0,
                  }}>{body}</p>
                </div>
              ))}
            </div>
          </div>
        </div>

        {/* ── Access ── */}
        <div style={{ maxWidth: 820, margin: '0 auto', padding: tight ? '48px 20px' : '68px 32px', textAlign: 'center' }}>
          <InviteBadge />
          <h2 style={{
            fontFamily: 'var(--font-display)', fontWeight: 700,
            fontSize: 'clamp(1.4rem, 2.8vw, 2rem)', color: 'var(--primary)',
            margin: '18px 0 10px', letterSpacing: '-0.01em',
          }}>
            Access is invite-only while Lekha is in preview
          </h2>
          <p style={{
            fontFamily: 'var(--font-body)', fontSize: 15, lineHeight: 1.75,
            color: 'var(--text-muted)', margin: '0 auto', maxWidth: '58ch',
          }}>
            There is no public sign-up. Accounts are created by invitation, and
            sign-in is restricted to approved addresses — deliberately, because
            this handles real financial statements and the guarantees are easier
            to keep at a small size. If you have an invite, sign in above.
          </p>
        </div>

        <footer style={{ borderTop: '1px solid var(--border)' }}>
          <div style={{
            maxWidth: 1180, margin: '0 auto', padding: '22px 32px',
            display: 'flex', gap: 14, flexWrap: 'wrap',
            alignItems: 'center', justifyContent: 'space-between',
            fontFamily: 'var(--font-mono)', fontSize: 11,
            letterSpacing: '0.06em', color: 'var(--text-dim)',
          }}>
            <span>LEKHA · लेखा — the account, the reckoning</span>
            <span>lekha.shiv.io · invite-only preview</span>
          </div>
        </footer>
      </div>
    );
  }

  window.finrLanding = { LandingPage };
})();
