/* global React, ReactDOM, TweaksPanel, useTweaks, TweakSection, TweakRadio, TweakColor, TweakToggle */
const { useState, useEffect } = React;

// ---------- Tweak defaults ----------
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "lang": "JP",
  "accent": "#F5B244",
  "serif": "Source Serif 4",
  "theme": "cream"
}/*EDITMODE-END*/;

const ACCENT_OPTIONS = ["#F5B244", "#5F8F86", "#0E1F1E", "#C97B3F"];
const SERIF_OPTIONS  = ["Source Serif 4", "EB Garamond", "Cormorant Garamond", "Libre Caslon Text"];
const THEME_OPTIONS  = [
  { value: "cream",   label: "Cream" },
  { value: "deep",    label: "Deep Sea" },
];

// ---------- Copy ----------
const COPY = {
  JP: {
    name:     "Masanori Uesugi",
    nameRoman:"Masanori Uesugi",
    eyebrow:  "Independent iOS Maker / Japan",
    bio: "個人開発でiOSアプリをつくっています。生活の隙間にそっと寄り添うような、小さくて静かな道具をめざして。SwiftUIとDynamic Islandが最近の関心ごと。",
    productsTitle: "Products",
    productsLead:  "これまでに公開したアプリ。",
    storeBadge: "App Store",
    contactTitle: "Get in touch",
    contactBody:  "新作のリリースや、考えごとをときどき。",
    placeholder:  "your@email.com",
    subscribe:    "Subscribe",
    footer:       "© 2026 Masanori Uesugi",
    tag:          "Quiet things, made slowly.",
  },
  EN: {
    name:     "Masanori Uesugi",
    nameRoman:"Masanori Uesugi",
    eyebrow:  "Independent iOS Maker / Japan",
    bio: "I build small iOS apps on my own. Quiet little tools that try to fit gently into the gaps of daily life. Lately my focus has been SwiftUI and the Dynamic Island.",
    productsTitle: "Products",
    productsLead:  "Apps I've released into the world.",
    storeBadge: "App Store",
    contactTitle: "Get in touch",
    contactBody:  "Occasional notes on new releases and what I'm thinking about.",
    placeholder:  "your@email.com",
    subscribe:    "Subscribe",
    footer:       "© 2026 Masanori Uesugi",
    tag:          "Quiet things, made slowly.",
  }
};

// ---------- Apps ----------
const APPS = [
  {
    id: "capty",
    year: "2025",
    nameJP: "Capty",
    nameEN: "Capty",
    taglineJP: "新感覚アート鑑賞ガイド",
    taglineEN: "A new way to look at art",
    blurbJP: "美術館の中でも外でも。一枚の作品とじっくり向きあうための、静かなガイドアプリ。",
    blurbEN: "A quiet guide for spending time with a single artwork — in a gallery, or anywhere.",
    url: "https://apps.apple.com/jp/app/capty-%E6%96%B0%E6%84%9F%E8%A6%9A%E3%82%A2%E3%83%BC%E3%83%88%E9%91%91%E8%B3%9E%E3%82%AC%E3%82%A4%E3%83%89/id6759860785",
    swatch: "linear-gradient(155deg, #2A3A47 0%, #5F8F86 70%, #A8B6AC 100%)",
    icon: "uploads/capty-icon.png",
    tag: "Art",
  },
  {
    id: "mypet",
    year: "2025",
    nameJP: "いつでもマイペット",
    nameEN: "Always My Pet",
    taglineJP: "ダイナミックアイランドの小さな癒やし",
    taglineEN: "A small comfort on the Dynamic Island",
    blurbJP: "iPhoneの上部に、ふとした瞬間あなたのペットが顔をのぞかせる。",
    blurbEN: "Your pet quietly peeks out from the top of your iPhone, now and then.",
    url: "https://apps.apple.com/jp/app/%E3%81%84%E3%81%A4%E3%81%A7%E3%82%82%E3%83%9E%E3%82%A4%E3%83%9A%E3%83%83%E3%83%88-%E3%83%80%E3%82%A4%E3%83%8A%E3%83%9F%E3%83%83%E3%82%AF%E3%82%A2%E3%82%A4%E3%83%A9%E3%83%B3%E3%83%89%E3%81%AE%E5%B0%8F%E3%81%95%E3%81%AA%E7%99%92%E3%82%84%E3%81%97/id6762539983",
    swatch: "linear-gradient(155deg, #F2D7A6 0%, #F5B244 65%, #C97B3F 100%)",
    icon: "uploads/always-my-pet-icon.png",
    tag: "Companion",
  },
];

// ---------- Icons (inline SVGs, no external libs) ----------
const Icon = {
  x:    (p) => (<svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor" {...p}><path d="M18.244 2H21l-6.55 7.49L22 22h-6.832l-4.83-6.31L4.8 22H2l7.04-8.04L2 2h6.95l4.36 5.77L18.244 2Zm-1.197 18h1.49L7.07 4H5.49l11.557 16Z"/></svg>),
  github:(p) => (<svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor" {...p}><path d="M12 .5a11.5 11.5 0 0 0-3.63 22.41c.57.1.78-.25.78-.55v-2c-3.2.7-3.88-1.36-3.88-1.36-.52-1.34-1.28-1.7-1.28-1.7-1.05-.72.08-.7.08-.7 1.17.08 1.78 1.2 1.78 1.2 1.04 1.78 2.72 1.27 3.38.97.1-.76.4-1.27.74-1.56-2.55-.29-5.24-1.28-5.24-5.7 0-1.26.46-2.3 1.2-3.1-.12-.3-.52-1.48.1-3.08 0 0 .97-.31 3.18 1.18a11 11 0 0 1 5.8 0c2.21-1.49 3.18-1.18 3.18-1.18.62 1.6.23 2.78.12 3.08.74.8 1.2 1.84 1.2 3.1 0 4.43-2.7 5.4-5.27 5.69.41.36.78 1.06.78 2.14v3.18c0 .3.21.66.79.55A11.5 11.5 0 0 0 12 .5Z"/></svg>),
  mail: (p) => (<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="3" y="5" width="18" height="14" rx="1"/><path d="m3 7 9 6 9-6"/></svg>),
  note: (p) => (<svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor" {...p}><circle cx="12" cy="12" r="10"/><path d="M7 12h10M12 7v10" stroke="var(--bg)" strokeWidth="1.8" strokeLinecap="round" fill="none"/></svg>),
  rss:  (p) => (<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M4 11a9 9 0 0 1 9 9"/><path d="M4 4a16 16 0 0 1 16 16"/><circle cx="5" cy="19" r="1.4" fill="currentColor" stroke="none"/></svg>),
};

// ---------- Components ----------
function Avatar() {
  // Placeholder portrait — soft sage circle with monogram
  return (
    <div className="avatar" aria-label="Profile portrait placeholder">
      <div className="avatar-inner">
        <span className="avatar-mono">MU</span>
      </div>
      <div className="avatar-ring" aria-hidden="true" />
    </div>
  );
}

function SocialDot({ href, label, children }) {
  return (
    <a className="social" href={href} target="_blank" rel="noopener noreferrer" aria-label={label}>
      {children}
    </a>
  );
}

function AppCard({ app, lang, t }) {
  const name    = lang === 'JP' ? app.nameJP    : app.nameEN;
  const tagline = lang === 'JP' ? app.taglineJP : app.taglineEN;
  const blurb   = lang === 'JP' ? app.blurbJP   : app.blurbEN;
  return (
    <a className="app-card" href={app.url} target="_blank" rel="noopener noreferrer"
       data-screen-label={`Work: ${app.id}`}>
      <div className="app-thumb" style={{background: app.swatch}}>
        <img className="app-icon" src={app.icon} alt="" aria-hidden="true" />
        <span className="app-thumb-top">
          <span className="app-thumb-year">{app.year}</span>
          <span className="app-thumb-tag">{app.tag}</span>
        </span>
      </div>
      <div className="app-body">
        <h3 className="app-name">{name}</h3>
        <p className="app-tagline">{tagline}</p>
        <p className="app-blurb">{blurb}</p>
        <div className="app-foot">
          <span className="store-badge">
            <svg viewBox="0 0 24 24" width="11" height="11" fill="currentColor" aria-hidden="true">
              <path d="M16.365 1.43c0 1.14-.46 2.22-1.21 3-.79.83-2.07 1.48-3.32 1.38-.15-1.1.4-2.27 1.13-3.05.81-.86 2.18-1.5 3.4-1.33Zm3.94 17.5c-.59 1.34-.87 1.94-1.62 3.13-.99 1.62-2.39 3.65-4.13 3.67-1.55.02-1.95-1-4.06-.99-2.11.02-2.55 1-4.1.98-1.74-.02-3.07-1.84-4.06-3.46-2.77-4.55-3.06-9.89-1.35-12.73 1.21-2.02 3.13-3.21 4.94-3.21 1.83 0 2.99 1.01 4.5 1.01 1.47 0 2.36-1.01 4.49-1.01 1.61 0 3.32.88 4.54 2.4-3.99 2.18-3.34 7.87.85 9.21Z"/>
            </svg>
            {t.storeBadge}
          </span>
          <span className="app-arrow" aria-hidden="true">↗</span>
        </div>
      </div>
    </a>
  );
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const lang = t.lang === 'EN' ? 'EN' : 'JP';
  const copy = COPY[lang];
  const [email, setEmail] = useState("");
  const [subState, setSubState] = useState("idle");

  // Live CSS variables
  useEffect(() => {
    const r = document.documentElement;
    r.style.setProperty('--accent', t.accent);
    r.style.setProperty('--font-serif',
      `"${t.serif}", "Noto Serif JP", Georgia, serif`);
    r.dataset.theme = t.theme;
  }, [t.accent, t.serif, t.theme]);

  function onSubscribe(e) {
    e.preventDefault();
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { setSubState("error"); return; }
    setSubState("sent");
    setTimeout(()=>{ setSubState("idle"); setEmail(""); }, 2400);
  }

  function toggleLang() {
    setTweak('lang', lang === 'JP' ? 'EN' : 'JP');
  }

  return (
    <div className="page" data-screen-label="Profile">
      {/* Top utility bar — tiny lang toggle, no nav */}
      <div className="topbar">
        <button className="lang-toggle" onClick={toggleLang} aria-label="Toggle language">
          <span className={lang==='JP'?"lang on":"lang"}>JP</span>
          <span className="lang-sep">/</span>
          <span className={lang==='EN'?"lang on":"lang"}>EN</span>
        </button>
      </div>

      <main className="stage">

        {/* Profile block */}
        <section className="profile">
          <Avatar />
          <div className="eyebrow">{copy.eyebrow}</div>
          <h1 className="name">{copy.name}</h1>
          {lang === 'JP' && copy.name !== copy.nameRoman && <div className="name-roman">{copy.nameRoman}</div>}
          <p className="bio">{copy.bio}</p>

          <div className="socials">
            <SocialDot href="https://x.com" label="X / Twitter">{Icon.x()}</SocialDot>
            <SocialDot href="https://github.com" label="GitHub">{Icon.github()}</SocialDot>
            <SocialDot href={APPS[0].url} label="App Store">
              <svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true">
                <path d="M16.365 1.43c0 1.14-.46 2.22-1.21 3-.79.83-2.07 1.48-3.32 1.38-.15-1.1.4-2.27 1.13-3.05.81-.86 2.18-1.5 3.4-1.33Zm3.94 17.5c-.59 1.34-.87 1.94-1.62 3.13-.99 1.62-2.39 3.65-4.13 3.67-1.55.02-1.95-1-4.06-.99-2.11.02-2.55 1-4.1.98-1.74-.02-3.07-1.84-4.06-3.46-2.77-4.55-3.06-9.89-1.35-12.73 1.21-2.02 3.13-3.21 4.94-3.21 1.83 0 2.99 1.01 4.5 1.01 1.47 0 2.36-1.01 4.49-1.01 1.61 0 3.32.88 4.54 2.4-3.99 2.18-3.34 7.87.85 9.21Z"/>
              </svg>
            </SocialDot>
            <SocialDot href="mailto:hello@example.com" label="Email">{Icon.mail()}</SocialDot>
          </div>
        </section>

        {/* Products */}
        <section className="products">
          <header className="block-head">
            <span className="block-label">{copy.productsTitle}</span>
            <p className="block-lead">{copy.productsLead}</p>
          </header>
          <div className="app-list">
            {APPS.map(a => <AppCard key={a.id} app={a} lang={lang} t={copy} />)}
          </div>
        </section>

        {/* Contact */}
        <section className="contact">
          <header className="block-head">
            <span className="block-label">{copy.contactTitle}</span>
            <p className="block-lead">{copy.contactBody}</p>
          </header>
          <form className="subscribe" onSubmit={onSubscribe}>
            <input
              type="email"
              value={email}
              onChange={(e)=>{setEmail(e.target.value); setSubState("idle");}}
              placeholder={copy.placeholder}
              aria-label="Email address"
              className={subState==='error'?"input err":"input"}
            />
            <button type="submit" className="btn-sub">
              {subState==='sent' ? (lang==='JP'?'登録しました ✓':'Subscribed ✓') : copy.subscribe}
            </button>
          </form>
        </section>

        <footer className="foot">
          <div className="foot-tag">{copy.tag}</div>
          <div className="foot-copy">{copy.footer}</div>
        </footer>
      </main>

      <TweaksPanel title="Tweaks">
        <TweakSection title="Language">
          <TweakRadio value={lang}
            options={[{value:'JP', label:'日本語'}, {value:'EN', label:'English'}]}
            onChange={(v)=>setTweak('lang', v)} />
        </TweakSection>
        <TweakSection title="Theme">
          <TweakRadio value={t.theme} options={THEME_OPTIONS}
            onChange={(v)=>setTweak('theme', v)} />
        </TweakSection>
        <TweakSection title="Accent">
          <TweakColor value={t.accent} options={ACCENT_OPTIONS}
            onChange={(v)=>setTweak('accent', v)} />
        </TweakSection>
        <TweakSection title="Serif">
          <TweakRadio value={t.serif}
            options={SERIF_OPTIONS.map(s=>({value:s, label:s.replace(' Garamond','').replace(' Caslon Text','')}))}
            onChange={(v)=>setTweak('serif', v)} />
        </TweakSection>
      </TweaksPanel>
    </div>
  );
}

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