/* global React, PhoneFrame, ScreenDashboard, ScreenExam, ScreenResult, ScreenProgress, ScreenHistory */

const RED = '#991600';
const PAPER = '#F7F6F2';
const PAPER_DEEP = '#EFEAE0';
const CARD = '#FFFFFF';
const BORDER = '#EDE8E1';
const TAN = '#EAD4BC';
const BROWN = '#A38B71';
const INK = '#000000';
const SAGE = '#586852';
const SAGE_PALE = '#DDE3DA';
const HIGHLIGHT = '#E6D8D6';

const fSys = '-apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", "Inter", system-ui, sans-serif';
const fJp = '"Noto Sans JP", "Hiragino Kaku Gothic ProN", "Yu Gothic", -apple-system, sans-serif';

// Returns true when viewport is narrower than the given breakpoint.
// Used to swap multi-column grids into stacks and to shrink decorative elements on phones.
function useIsMobile(breakpoint = 768) {
  const get = () => typeof window !== 'undefined' && window.innerWidth < breakpoint;
  const [isMobile, setIsMobile] = React.useState(get);
  React.useEffect(() => {
    const onResize = () => setIsMobile(get());
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, [breakpoint]);
  return isMobile;
}

// Days until the next JLPT.
// Hardcoded against the official JEES exam calendar — update when new dates are announced.
const JLPT_DATES = [
  '2026-07-05',
  '2026-12-06',
  '2027-07-04',
  '2027-12-05',
];
function daysUntilJLPT(now = new Date()) {
  const startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate());
  const next = JLPT_DATES
    .map((s) => {
      const [y, m, d] = s.split('-').map(Number);
      return new Date(y, m - 1, d);
    })
    .find((d) => d >= startOfToday);
  if (!next) return 0;
  return Math.max(0, Math.round((next - startOfToday) / 86400000));
}

// ---------- Reusable bits ----------
function Wordmark({ size = 36, color = RED }) {
  return (
    <span style={{
      fontFamily: fSys, fontWeight: 700,
      fontSize: size, lineHeight: 0.9, color,
      letterSpacing: '-0.04em'
    }}>junbi</span>);

}

function NotifyForm({ caption, captionColor, size = 'lg', source = 'landing' }) {
  const [email, setEmail] = React.useState('');
  const [website, setWebsite] = React.useState('');
  const [submitted, setSubmitted] = React.useState(false);
  const [error, setError] = React.useState('');
  const [pending, setPending] = React.useState(false);
  const isLarge = size === 'lg';
  const inputH = isLarge ? 52 : 46;
  const onSubmit = async (e) => {
    e.preventDefault();
    if (!email.trim() || pending) return;
    setPending(true);
    setError('');
    try {
      const r = await fetch('/api/subscribe', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email: email.trim(), website, source }),
      });
      if (!r.ok) {
        const data = await r.json().catch(() => ({}));
        setError(data.error === 'Invalid email' ? 'Please enter a valid email.' : 'Something went wrong. Try again.');
        setPending(false);
        return;
      }
      setSubmitted(true);
    } catch {
      setError('Network error. Try again.');
      setPending(false);
    }
  };
  return (
    <form onSubmit={onSubmit} style={{ display: 'flex', flexDirection: 'column', gap: 10, maxWidth: 520, width: '100%' }}>
      {submitted ? (
        <div style={{
          display: 'flex', alignItems: 'center', gap: 12,
          padding: `0 ${isLarge ? 20 : 16}px`,
          height: inputH, borderRadius: 10,
          border: `1px solid ${SAGE}`, background: SAGE_PALE,
          font: `500 ${isLarge ? 15 : 14}px ${fSys}`, color: '#3a4a36',
        }}>
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
            <path d="M5 12l4 4L19 7" />
          </svg>
          <span>Thanks — I'll email you when N5 ships.</span>
        </div>
      ) : (
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
          <input
            type="text"
            tabIndex={-1}
            autoComplete="off"
            value={website}
            onChange={(e) => setWebsite(e.target.value)}
            aria-hidden="true"
            style={{ position: 'absolute', left: '-10000px', width: 1, height: 1, opacity: 0 }}
          />
          <input
            type="email"
            required
            disabled={pending}
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            placeholder="you@example.com"
            style={{
              flex: '1 1 240px', minWidth: 0, height: inputH,
              padding: `0 ${isLarge ? 18 : 14}px`,
              border: `1px solid ${BORDER}`, borderRadius: 10,
              background: PAPER, color: INK, outline: 'none',
              font: `400 ${isLarge ? 16 : 15}px ${fSys}`,
              boxSizing: 'border-box',
            }}
          />
          <button type="submit" disabled={pending} style={{
            height: inputH, padding: `0 ${isLarge ? 24 : 20}px`,
            background: RED, color: PAPER, border: 'none',
            borderRadius: 10, cursor: pending ? 'wait' : 'pointer',
            opacity: pending ? 0.7 : 1,
            font: `600 ${isLarge ? 15 : 14}px ${fSys}`, letterSpacing: '0.01em',
          }}>{pending ? 'Sending…' : 'Get notified'}</button>
        </div>
      )}
      {error && !submitted && (
        <span style={{ font: `400 13px ${fSys}`, color: RED }}>{error}</span>
      )}
      {caption && !error && (
        <span style={{ font: `400 13px ${fSys}`, color: captionColor || BROWN }}>{caption}</span>
      )}
    </form>
  );
}

function AppStoreBadge({ small = false }) {
  // Hand-built — ink-on-paper aesthetic with sumi-red Apple mark.
  const w = small ? 156 : 184;
  const h = small ? 52 : 60;
  return (
    <a href="#download" style={{
      display: 'inline-flex', alignItems: 'center', gap: 12,
      width: w, height: h, padding: '0 18px',
      background: '#000', color: '#fff',
      borderRadius: 12, textDecoration: 'none',
      boxSizing: 'border-box'
    }}>
      <svg width={small ? 22 : 26} height={small ? 26 : 32} viewBox="0 0 24 28" fill="currentColor">
        <path d="M19.7 21.6c-1.05 1.55-2.15 3.1-3.85 3.13-1.7.03-2.25-1-4.2-1s-2.55 1-4.15 1.04C5.83 24.8 4.6 23.05 3.5 21.5 1.3 18.4-.4 12.65 1.9 8.8 3.04 6.9 5.07 5.7 7.27 5.66c1.65-.03 3.2 1.1 4.2 1.1 1 0 2.9-1.36 4.9-1.16.83.04 3.18.34 4.7 2.55-.13.08-2.8 1.65-2.78 4.92.03 3.9 3.4 5.2 3.43 5.22-.03.08-.55 1.85-1.75 3.4M13 3.4C13.95 2.3 15.5 1.5 16.8 1.45c.18 1.4-.42 2.83-1.35 3.83-.92 1-2.45 1.78-3.95 1.66C11.27 5.55 11.95 4.45 13 3.4z" />
      </svg>
      <span style={{ display: 'flex', flexDirection: 'column', lineHeight: 1, gap: small ? 2 : 3 }}>
        <span style={{ font: `400 ${small ? 10 : 11}px ${fSys}`, opacity: 0.85 }}>Download on the</span>
        <span style={{ font: `600 ${small ? 18 : 21}px ${fSys}`, letterSpacing: '-0.01em' }}>App Store</span>
      </span>
    </a>);

}

function StampIllustration({ section, size = 92, opacity = 1 }) {
  return (
    <img src={`assets/hanko-${section}.svg`} alt="" style={{ width: size, height: size, opacity }} />);

}

function SectionEyebrow({ children }) {
  return (
    <div style={{
      font: `700 12px ${fSys}`, color: RED, letterSpacing: '0.18em',
      textTransform: 'uppercase', fontFamily: fSys
    }}>{children}</div>);

}

function SectionHeading({ children, size = 56 }) {
  const minSize = Math.max(28, Math.round(size * 0.55));
  return (
    <h2 style={{
      fontWeight: 600,
      fontSize: `clamp(${minSize}px, 6vw, ${size}px)`,
      fontFamily: fSys,
      lineHeight: 1.05, letterSpacing: '-0.02em',
      color: INK, margin: 0, textWrap: 'balance'
    }}>{children}</h2>);

}

function HairlineRule() {
  return <div style={{ height: 1, background: BORDER, width: '100%' }} />;
}

// ---------- Bot-resistant mailto ----------
// Renders a plain text "user [at] domain.tld" until JS runs, then hydrates into
// a real mailto: link client-side. Bots scraping HTML source see no mailto.
function ProtectedEmail({ user, domain, subject, label, style }) {
  const [hydrated, setHydrated] = React.useState(false);
  React.useEffect(() => { setHydrated(true); }, []);
  const display = label || `${user}@${domain}`;
  const fallback = `${user} [at] ${domain}`;
  const href = subject
    ? `mailto:${user}@${domain}?subject=${encodeURIComponent(subject)}`
    : `mailto:${user}@${domain}`;
  if (!hydrated) {
    return <span style={style}>{fallback}</span>;
  }
  return (
    <a href={href} style={style}>{display}</a>
  );
}

// ---------- Top Nav ----------
function TopNav() {
  const isMobile = useIsMobile();
  // Detect whether we're on the landing page; if not, prefix anchors with the landing URL.
  const isLanding = typeof location !== 'undefined' &&
    /(^\/?$)|(Junbi%20Landing%20Page\.html$)|(Junbi Landing Page\.html$)|(index\.html$)/i.test(location.pathname);
  const home = 'index.html';
  const link = (anchor) => isLanding ? `#${anchor}` : `${home}#${anchor}`;
  return (
    <header style={{
      position: 'sticky', top: 0, zIndex: 100,
      background: PAPER,
      borderBottom: `1px solid ${BORDER}`,
      padding: isMobile ? '12px 20px' : '14px 32px',
    }}>
      <div style={{
        maxWidth: 1240, margin: '0 auto',
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      }}>
        <a href={isLanding ? '#' : home} style={{ display: 'flex', alignItems: 'center', gap: 10, marginLeft: -3, textDecoration: 'none' }}>
          <Wordmark size={isMobile ? 26 : 30} />
          <span style={{ fontFamily: fJp, fontSize: isMobile ? 16 : 18, color: BROWN }}>準備</span>
        </a>
        <nav style={{ display: 'flex', alignItems: 'center', gap: isMobile ? 0 : 32, font: `500 14px ${fSys}`, color: '#1f1f1f' }}>
          {!isMobile && (
            <>
              <a href={link('how')} style={{ color: 'inherit', textDecoration: 'none' }}>How it works</a>
              <a href={link('sections')} style={{ color: 'inherit', textDecoration: 'none' }}>Sections</a>
              <a href={link('faq')} style={{ color: 'inherit', textDecoration: 'none' }}>FAQ</a>
            </>
          )}
          <a href={link('download')} style={{
            display: 'inline-flex', alignItems: 'center', height: isMobile ? 36 : 40, padding: isMobile ? '0 14px' : '0 18px',
            background: RED, color: PAPER, borderRadius: 9999,
            font: `700 ${isMobile ? 12 : 13}px ${fSys}`, textDecoration: 'none'
          }}>Get notified</a>
        </nav>
      </div>
    </header>);

}

Object.assign(window, {
  RED, PAPER, PAPER_DEEP, CARD, BORDER, TAN, BROWN, INK, SAGE, SAGE_PALE, HIGHLIGHT,
  fSys, fJp,
  daysUntilJLPT,
  Wordmark, AppStoreBadge, NotifyForm, ProtectedEmail, StampIllustration, SectionEyebrow, SectionHeading, HairlineRule,
  TopNav, useIsMobile,
});