/* global React, ReactDOM */
const { useState, useEffect, useMemo, useRef } = React;

// ================== ORIGIN DATA ==================
const ORIGINS = [
  {
    id: 'br', code: 'BR',
    name: { jp: 'ブラジル', en: 'Brazil' },
    region: { jp: 'Campo das Vertentes · Minas Gerais', en: 'Campo das Vertentes · Minas Gerais' },
    importer: 'Mirai Seeds Inc.',
    importerSub: { jp: 'グアリロバ農園 オフィシャルパートナー', en: 'Official partner — Fazenda Guariroba' },
    varieties: 'Yellow Topázio · Catuaí · Mundo Novo',
    process: { jp: 'Natural / Honey / 嫌気性', en: 'Natural / Honey / Anaerobic' },
    notes: { jp: 'チョコレート、キャラメル、トロピカルフルーツ', en: 'Chocolate, caramel, tropical fruit' },
    pos: { x: 30.5, y: 64 },   // map %
    flag: 'br'
  },
  {
    id: 'pa', code: 'PA',
    name: { jp: 'パナマ', en: 'Panama' },
    region: { jp: 'Boquete · Volcán · Chiriquí', en: 'Boquete · Volcán · Chiriquí' },
    importer: 'Brisa and Tierra',
    importerSub: { jp: 'パナマ専門商社', en: 'Panama-focused importer' },
    varieties: 'Geisha · Caturra · Typica',
    process: { jp: 'Washed / Natural / Anaerobic', en: 'Washed / Natural / Anaerobic' },
    notes: { jp: 'ジャスミン、ベルガモット、ピーチ', en: 'Jasmine, bergamot, peach' },
    pos: { x: 24.5, y: 52 },
    flag: 'pa'
  },
  {
    id: 'tw', code: 'TW',
    name: { jp: '台湾', en: 'Taiwan' },
    region: { jp: 'Yunlin · Nantou · Alishan', en: 'Yunlin · Nantou · Alishan' },
    importer: 'ORIOWL Co., Ltd.',
    importerSub: { jp: '台湾珈琲専門商社', en: 'Taiwan coffee specialist' },
    varieties: 'Typica · SL34 · Geisha',
    process: { jp: 'Natural / Honey / Wine', en: 'Natural / Honey / Wine' },
    notes: { jp: '紅茶、ライチ、和柑橘', en: 'Black tea, lychee, citrus' },
    pos: { x: 78.5, y: 48 },
    flag: 'tw'
  },
  {
    id: 'cr', code: 'CR',
    name: { jp: 'コスタリカ', en: 'Costa Rica' },
    region: { jp: 'Tarrazú · West Valley · Naranjo', en: 'Tarrazú · West Valley · Naranjo' },
    importer: 'PuraVida',
    importerSub: { jp: 'コスタリカ専門商社', en: 'Costa Rica specialist' },
    varieties: 'Caturra · Catuaí · Villa Sarchi',
    process: { jp: 'White / Yellow / Black Honey', en: 'White / Yellow / Black Honey' },
    notes: { jp: 'シトラス、シュガーケーン、フローラル', en: 'Citrus, sugarcane, floral' },
    pos: { x: 25, y: 50.5 },
    flag: 'cr'
  },
  {
    id: 'id', code: 'ID',
    name: { jp: 'インドネシア', en: 'Indonesia' },
    region: { jp: 'Sumatra · Sulawesi · Java', en: 'Sumatra · Sulawesi · Java' },
    importer: 'Rational Idea Inc.',
    importerSub: { jp: 'Asosiasi Kopi Indonesia 日本総代理店', en: 'Japan agent for Asosiasi Kopi Indonesia' },
    varieties: 'Tim Tim · Lini-S · Sigararutang',
    process: { jp: 'Wet Hulled / Natural / Honey', en: 'Wet Hulled / Natural / Honey' },
    notes: { jp: 'スパイス、ハーブ、ダークチョコ', en: 'Spice, herbs, dark chocolate' },
    pos: { x: 80, y: 64 },
    flag: 'id'
  }
];

// ================== FLAG SVGs ==================
const Flag = ({ code }) => {
  switch(code){
    case 'br': return (
      <svg viewBox="0 0 36 24"><rect width="36" height="24" fill="#009C3B"/><path d="M18 4 L32 12 L18 20 L4 12 Z" fill="#FFDF00"/><circle cx="18" cy="12" r="4.5" fill="#002776"/><path d="M13.5 12.4 a4.5 4.5 0 0 1 9 0" stroke="#fff" strokeWidth=".5" fill="none"/></svg>
    );
    case 'pa': return (
      <svg viewBox="0 0 36 24"><rect width="18" height="12" fill="#fff"/><rect x="18" width="18" height="12" fill="#D21034"/><rect y="12" width="18" height="12" fill="#0072CE"/><rect x="18" y="12" width="18" height="12" fill="#fff"/><polygon points="9,3 10,5.5 12.7,5.5 10.5,7 11.5,9.7 9,8 6.5,9.7 7.5,7 5.3,5.5 8,5.5" fill="#0072CE"/><polygon points="27,15 28,17.5 30.7,17.5 28.5,19 29.5,21.7 27,20 24.5,21.7 25.5,19 23.3,17.5 26,17.5" fill="#D21034"/></svg>
    );
    case 'tw': return (
      <svg viewBox="0 0 36 24"><rect width="36" height="24" fill="#FE0000"/><rect width="18" height="12" fill="#000095"/><circle cx="9" cy="6" r="3.6" fill="#FFF"/><circle cx="9" cy="6" r="2.6" fill="#000095"/><g fill="#FFF"><polygon points="9,2.4 9.4,4.8 11.6,4.4 9.8,6 11.6,7.6 9.4,7.2 9,9.6 8.6,7.2 6.4,7.6 8.2,6 6.4,4.4 8.6,4.8"/></g></svg>
    );
    case 'cr': return (
      <svg viewBox="0 0 36 24"><rect width="36" height="24" fill="#0072CE"/><rect y="4" width="36" height="16" fill="#fff"/><rect y="9" width="36" height="6" fill="#CE1126"/></svg>
    );
    case 'id': return (
      <svg viewBox="0 0 36 24"><rect width="36" height="12" fill="#FF0000"/><rect y="12" width="36" height="12" fill="#fff"/></svg>
    );
    default: return null;
  }
};

// ================== ORIGIN MAP APP ==================
const OriginApp = () => {
  const lang = useLang();
  const [activeId, setActiveId] = useState('br');
  const active = ORIGINS.find(o => o.id === activeId) || ORIGINS[0];
  const idx = ORIGINS.findIndex(o => o.id === activeId);

  const next = () => setActiveId(ORIGINS[(idx+1) % ORIGINS.length].id);
  const prev = () => setActiveId(ORIGINS[(idx-1+ORIGINS.length) % ORIGINS.length].id);

  return (
    <>
      <div className="origin-map">
        <svg viewBox="0 0 100 60" preserveAspectRatio="none">
          {/* simplified continents */}
          {/* North America */}
          <path className={`land ${['cr'].includes(activeId)?'active':''}`} d="M5 14 L18 12 L24 18 L26 26 L22 38 L26 50 L20 52 L14 46 L8 36 Z"/>
          {/* South America */}
          <path className={`land ${['br'].includes(activeId)?'active':''}`} d="M22 38 L34 38 L36 48 L34 56 L28 58 L22 56 L20 50 L22 44 Z"/>
          {/* Europe */}
          <path className="land" d="M44 14 L58 12 L60 18 L56 24 L48 24 L44 20 Z"/>
          {/* Africa */}
          <path className="land" d="M48 26 L60 26 L62 36 L58 48 L52 50 L48 42 L46 32 Z"/>
          {/* Asia */}
          <path className={`land ${['tw'].includes(activeId)?'active':''}`} d="M58 12 L86 14 L92 22 L88 30 L80 32 L70 28 L62 24 L58 18 Z"/>
          {/* SE Asia / Indonesia */}
          <path className={`land ${['id'].includes(activeId)?'active':''}`} d="M74 36 L88 36 L92 40 L86 44 L78 42 L74 40 Z"/>
          {/* Australia */}
          <path className="land" d="M82 46 L94 46 L96 52 L88 54 L82 50 Z"/>

          {/* Pins */}
          {ORIGINS.map(o => (
            <g key={o.id}
               className={`pin ${activeId === o.id ? 'is-on' : ''}`}
               transform={`translate(${o.pos.x}, ${o.pos.y})`}
               onClick={() => setActiveId(o.id)}>
              <circle className="ring" r="6"/>
              <circle className="core" r="1.4"/>
              <text className="label" x="0" y="-3" textAnchor="middle">{o.code}</text>
            </g>
          ))}
        </svg>
        <div className="legend"><span style={{display:'inline-block',width:6,height:6,borderRadius:'50%',background:'var(--gold)'}}/>{lang==='jp'?'産地ネットワーク':'Origin Network'}</div>
        <div className="compass">N · 東 · S · 西</div>
        <div className="scale">5 origins · growing</div>
      </div>

      <div className="origin-card">
        <div className="origin-card__top">
          <div style={{display:'flex',alignItems:'center',gap:14}}>
            <div className="origin-card__flag"><Flag code={active.flag}/></div>
            <div>
              <div style={{fontSize:11,letterSpacing:'.18em',textTransform:'uppercase',color:'rgba(250,250,247,.5)',fontWeight:500}}>{active.code}</div>
              <h3>{active.name[lang]}</h3>
              <div className="region">{active.region[lang]}</div>
            </div>
          </div>
          <span className="origin-card__no">N° 0{idx+1}</span>
        </div>

        <div className="origin-card__importer">
          <span>{lang==='jp'?'参加インポーター':'Member Importer'}</span>
          <div style={{textAlign:'right'}}>
            <b>{active.importer}</b>
            <div style={{fontSize:11,color:'rgba(250,250,247,.5)',marginTop:2}}>{active.importerSub[lang]}</div>
          </div>
        </div>

        <dl className="origin-card__notes">
          <div><dt>Varieties</dt><dd>{active.varieties}</dd></div>
          <div><dt>Process</dt><dd>{active.process[lang]}</dd></div>
          <div style={{gridColumn:'1 / -1'}}><dt>{lang==='jp'?'カップノート':'Cup Notes'}</dt><dd style={{fontFamily:'Fraunces, serif',fontStyle:'italic'}}>"{active.notes[lang]}"</dd></div>
        </dl>

        <div className="origin-card__nav">
          <button onClick={prev}>← {lang==='jp'?'前の産地':'Prev'}</button>
          <span>{idx+1} / {ORIGINS.length}</span>
          <button onClick={next}>{lang==='jp'?'次の産地':'Next'} →</button>
        </div>
      </div>
    </>
  );
};

const OriginTabs = () => {
  const lang = useLang();
  const [activeId, setActiveId] = useState('br');
  // sync with map by listening to clicks on .pin (kept simple — internal)
  return (
    <>
      {ORIGINS.map(o => (
        <button
          key={o.id}
          className={`origin-tab ${activeId===o.id?'active':''}`}
          onClick={() => {
            setActiveId(o.id);
            // also update map
            const ev = new CustomEvent('origin-jump', { detail: o.id });
            window.dispatchEvent(ev);
          }}>
          <div className="num">N° 0{ORIGINS.indexOf(o)+1}</div>
          <div className="name">{o.name[lang]} <span style={{opacity:.5,fontWeight:400}}>· {o.code}</span></div>
          <div className="sub">{o.importer}</div>
        </button>
      ))}
    </>
  );
};

// ================== Lang hook ==================
function useLang(){
  const [lang, setLang] = useState(document.body.dataset.lang || 'jp');
  useEffect(() => {
    const obs = new MutationObserver(() => {
      setLang(document.body.dataset.lang || 'jp');
    });
    obs.observe(document.body, { attributes: true, attributeFilter: ['data-lang'] });
    return () => obs.disconnect();
  }, []);
  return lang;
}

// ================== Combined Origins (single state, two views) ==================
const OriginsModule = () => {
  const lang = useLang();
  const [activeId, setActiveId] = useState('br');
  const active = ORIGINS.find(o => o.id === activeId) || ORIGINS[0];
  const idx = ORIGINS.findIndex(o => o.id === activeId);
  const next = () => setActiveId(ORIGINS[(idx+1) % ORIGINS.length].id);
  const prev = () => setActiveId(ORIGINS[(idx-1+ORIGINS.length) % ORIGINS.length].id);

  return (
    <>
      <div className="origin-app" style={{display:'grid',gridTemplateColumns:'1.4fr 1fr',gap:40}}>
        <div className="origin-map">
          <svg viewBox="0 0 100 60" preserveAspectRatio="none">
            <path className="land" d="M5 14 L18 12 L24 18 L26 26 L22 38 L26 50 L20 52 L14 46 L8 36 Z"/>
            <path className={`land ${activeId==='br'?'active':''}`} d="M22 38 L34 38 L36 48 L34 56 L28 58 L22 56 L20 50 L22 44 Z"/>
            <path className="land" d="M44 14 L58 12 L60 18 L56 24 L48 24 L44 20 Z"/>
            <path className="land" d="M48 26 L60 26 L62 36 L58 48 L52 50 L48 42 L46 32 Z"/>
            <path className={`land ${activeId==='tw'?'active':''}`} d="M58 12 L86 14 L92 22 L88 30 L80 32 L70 28 L62 24 L58 18 Z"/>
            <path className={`land ${activeId==='id'?'active':''}`} d="M74 36 L88 36 L92 40 L86 44 L78 42 L74 40 Z"/>
            <path className="land" d="M82 46 L94 46 L96 52 L88 54 L82 50 Z"/>
            {ORIGINS.map(o => (
              <g key={o.id}
                 className={`pin ${activeId === o.id ? 'is-on' : ''}`}
                 transform={`translate(${o.pos.x}, ${o.pos.y})`}
                 onClick={() => setActiveId(o.id)}>
                <circle className="ring" r="6"/>
                <circle className="core" r="1.4"/>
                <text className="label" x="0" y="-3" textAnchor="middle">{o.code}</text>
              </g>
            ))}
          </svg>
          <div className="legend">
            <span style={{display:'inline-block',width:6,height:6,borderRadius:'50%',background:'var(--gold)'}}/>
            {lang==='jp'?'産地ネットワーク':'Origin Network'}
          </div>
          <div className="compass">{lang==='jp'?'5 産地 · 拡大中':'5 origins · growing'}</div>
          <div className="scale">click any pin</div>
        </div>

        <div className="origin-card">
          <div className="origin-card__top">
            <div style={{display:'flex',alignItems:'center',gap:14}}>
              <div className="origin-card__flag"><Flag code={active.flag}/></div>
              <div>
                <div style={{fontSize:11,letterSpacing:'.18em',textTransform:'uppercase',color:'rgba(250,250,247,.5)',fontWeight:500}}>{active.code}</div>
                <h3>{active.name[lang]}</h3>
                <div className="region">{active.region[lang]}</div>
              </div>
            </div>
            <span className="origin-card__no">N° 0{idx+1}</span>
          </div>

          <div className="origin-card__importer">
            <span>{lang==='jp'?'参加インポーター':'Member Importer'}</span>
            <div style={{textAlign:'right'}}>
              <b>{active.importer}</b>
              <div style={{fontSize:11,color:'rgba(250,250,247,.5)',marginTop:2}}>{active.importerSub[lang]}</div>
            </div>
          </div>

          <dl className="origin-card__notes">
            <div><dt>Varieties</dt><dd>{active.varieties}</dd></div>
            <div><dt>Process</dt><dd>{active.process[lang]}</dd></div>
            <div style={{gridColumn:'1 / -1'}}>
              <dt>{lang==='jp'?'カップノート':'Cup Notes'}</dt>
              <dd style={{fontFamily:'Fraunces, serif',fontStyle:'italic'}}>"{active.notes[lang]}"</dd>
            </div>
          </dl>

          <div className="origin-card__nav">
            <button onClick={prev}>← {lang==='jp'?'前へ':'Prev'}</button>
            <span>{idx+1} / {ORIGINS.length}</span>
            <button onClick={next}>{lang==='jp'?'次へ':'Next'} →</button>
          </div>
        </div>
      </div>

      <div className="origin-tabs reveal in">
        {ORIGINS.map((o, i) => (
          <button
            key={o.id}
            className={`origin-tab ${activeId===o.id?'active':''}`}
            onClick={() => setActiveId(o.id)}>
            <div className="num">N° 0{i+1}</div>
            <div className="name">{o.name[lang]} <span style={{opacity:.5,fontWeight:400}}>· {o.code}</span></div>
            <div className="sub">{o.importer}</div>
          </button>
        ))}
      </div>
    </>
  );
};

// ================== SAMPLE FORM (multi-step) ==================
const SampleForm = () => {
  const lang = useLang();
  const [step, setStep] = useState(0);
  const [data, setData] = useState({
    company: '', name: '', email: '', phone: '',
    role: '',
    origins: [],
    quantity: 'small',
    process: [],
    purpose: '',
    timing: 'asap',
    notes: ''
  });
  const [done, setDone] = useState(false);

  const update = (k, v) => setData(d => ({ ...d, [k]: v }));
  const toggleArr = (k, v) => setData(d => {
    const arr = d[k];
    return { ...d, [k]: arr.includes(v) ? arr.filter(x => x !== v) : [...arr, v] };
  });

  const t = (jp, en) => lang === 'jp' ? jp : en;

  const steps = [
    { key: 'origins', label: t('産地選択', 'Origins') },
    { key: 'detail',  label: t('詳細', 'Details') },
    { key: 'contact', label: t('連絡先', 'Contact') }
  ];

  const canNext = () => {
    if(step === 0) return data.origins.length > 0;
    if(step === 1) return data.purpose.length > 0;
    if(step === 2) return data.company && data.name && data.email;
    return true;
  };

  const submit = () => {
    // Submit to Contact Form 7 if linkoneCF7 (window.linkoneCF7) is configured
    if (window.linkoneCF7 && window.linkoneCF7.sampleFormId && window.linkoneCF7.restUrl) {
      const form = new FormData();
      form.append('your-company', data.company);
      form.append('your-name', data.name);
      form.append('your-email', data.email);
      form.append('your-phone', data.phone || '');
      form.append('your-role', data.role || '');
      form.append('your-origins', data.origins.map(id => {
        const o = ORIGINS.find(x => x.id === id);
        return o ? o.name.en : id;
      }).join(', '));
      form.append('your-process', data.process.join(', '));
      form.append('your-quantity', data.quantity);
      form.append('your-purpose', data.purpose);
      form.append('your-timing', data.timing);
      form.append('your-message', data.notes || '');
      const url = window.linkoneCF7.restUrl + 'contact-form-7/v1/contact-forms/' + window.linkoneCF7.sampleFormId + '/feedback';
      fetch(url, { method: 'POST', body: form, credentials: 'same-origin' })
        .then(r => r.json())
        .then(res => {
          if (res.status === 'mail_sent' || res.status === 'mail_failed') {
            setDone(true);
          } else {
            // Validation issue: show message but still mark done with a soft warning
            console.warn('CF7 response:', res);
            setDone(true);
          }
        })
        .catch(err => {
          console.error('CF7 submit error:', err);
          setDone(true); // optimistic
        });
    } else {
      // Fallback: just mark complete (dev / no CF7 installed)
      setDone(true);
    }
  };

  if(done){
    return (
      <div className="form-success">
        <div className="form-success__check">
          <svg width="22" height="22" viewBox="0 0 22 22" fill="none"><path d="M5 11.5l4 4 8-9" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>
        </div>
        <h3>{t('依頼を受け付けました', 'Request received')}</h3>
        <p>{t(`${data.company} 様、ありがとうございます。担当者より3営業日以内にご連絡を差し上げます。`,
              `Thank you, ${data.company}. A LinkOne member will reach out within 3 business days.`)}</p>
        <button className="btn btn--ghost" onClick={() => { setStep(0); setDone(false); setData({company:'',name:'',email:'',phone:'',role:'',origins:[],quantity:'small',process:[],purpose:'',timing:'asap',notes:''}); }}>
          {t('別の依頼を作成', 'New request')}
        </button>
      </div>
    );
  }

  return (
    <>
      <div className="form-steps">
        {steps.map((s, i) => (
          <div key={s.key} className={`form-step ${i===step?'active':''} ${i<step?'done':''}`}>
            <div className="n">{i<step ? '✓' : i+1}</div>
            <span>{s.label}</span>
          </div>
        ))}
      </div>

      {/* Step 0 - Origins */}
      {step === 0 && (
        <div>
          <div className="field">
            <label>{t('興味のある産地を選択', 'Select origins of interest')} <span className="req">*</span></label>
            <div className="help">{t('複数選択可。今後参加予定の産地も対象です。', 'Multiple selections welcome.')}</div>
          </div>
          <div className="checks" style={{gridTemplateColumns:'repeat(auto-fill,minmax(180px,1fr))'}}>
            {ORIGINS.map(o => (
              <label key={o.id} className={`check ${data.origins.includes(o.id)?'on':''}`}>
                <input type="checkbox" checked={data.origins.includes(o.id)} onChange={() => toggleArr('origins', o.id)}/>
                <span className="box"></span>
                <span className="lab">
                  <b>{o.name[lang]} · {o.code}</b>
                  <span>{o.importer}</span>
                </span>
              </label>
            ))}
          </div>

          <div style={{marginTop:24}}>
            <div className="field">
              <label>{t('精製方法（任意）', 'Process preferences (optional)')}</label>
            </div>
            <div className="checks">
              {['Washed','Natural','Honey','Anaerobic','Wet Hulled'].map(p => (
                <label key={p} className={`check ${data.process.includes(p)?'on':''}`}>
                  <input type="checkbox" checked={data.process.includes(p)} onChange={() => toggleArr('process', p)}/>
                  <span className="box"></span>
                  <span className="lab"><b>{p}</b></span>
                </label>
              ))}
            </div>
          </div>
        </div>
      )}

      {/* Step 1 - Detail */}
      {step === 1 && (
        <div>
          <div className="field">
            <label>{t('使用目的・想定する用途', 'Intended use')} <span className="req">*</span></label>
            <textarea value={data.purpose} onChange={e=>update('purpose', e.target.value)} placeholder={t('例: シングルオリジンとして店頭で販売予定。エスプレッソ・ドリップ両対応のロットを希望。', 'e.g. Single origin offering for retail; suitable for both espresso and drip.')}/>
          </div>

          <div className="field">
            <label>{t('希望サンプル量', 'Sample size')}</label>
            <div className="checks" style={{gridTemplateColumns:'repeat(3,1fr)'}}>
              {[
                {v:'small', lab: t('100g 程度','~100g'), sub: t('テイスティング向け','For tasting')},
                {v:'medium', lab: t('300g - 500g','300g – 500g'), sub: t('焙煎テスト向け','Roast testing')},
                {v:'large', lab: t('1kg 以上','1kg or more'), sub: t('量産前の検証','Pre-production')}
              ].map(o => (
                <label key={o.v} className={`check ${data.quantity===o.v?'on':''}`}>
                  <input type="radio" checked={data.quantity===o.v} onChange={()=>update('quantity', o.v)}/>
                  <span className="box"></span>
                  <span className="lab"><b>{o.lab}</b><span>{o.sub}</span></span>
                </label>
              ))}
            </div>
          </div>

          <div className="field">
            <label>{t('ご希望の時期', 'Timing')}</label>
            <select value={data.timing} onChange={e=>update('timing', e.target.value)}>
              <option value="asap">{t('できるだけ早く', 'As soon as possible')}</option>
              <option value="month">{t('1ヶ月以内', 'Within 1 month')}</option>
              <option value="quarter">{t('3ヶ月以内', 'Within 3 months')}</option>
              <option value="flex">{t('時期は柔軟', 'Flexible')}</option>
            </select>
          </div>

          <div className="field">
            <label>{t('その他ご要望（任意）', 'Other notes (optional)')}</label>
            <textarea value={data.notes} onChange={e=>update('notes', e.target.value)}/>
          </div>
        </div>
      )}

      {/* Step 2 - Contact */}
      {step === 2 && (
        <div>
          <div className="form-grid-2">
            <div className="field">
              <label>{t('会社・屋号名', 'Company / Roastery name')} <span className="req">*</span></label>
              <input type="text" value={data.company} onChange={e=>update('company', e.target.value)}/>
            </div>
            <div className="field">
              <label>{t('役職', 'Role')}</label>
              <input type="text" value={data.role} onChange={e=>update('role', e.target.value)} placeholder={t('代表 / バイヤー / ロースター 等', 'Owner / Buyer / Roaster')}/>
            </div>
          </div>
          <div className="form-grid-2">
            <div className="field">
              <label>{t('ご担当者名', 'Your name')} <span className="req">*</span></label>
              <input type="text" value={data.name} onChange={e=>update('name', e.target.value)}/>
            </div>
            <div className="field">
              <label>{t('電話番号', 'Phone')}</label>
              <input type="tel" value={data.phone} onChange={e=>update('phone', e.target.value)}/>
            </div>
          </div>
          <div className="field">
            <label>Email <span className="req">*</span></label>
            <input type="email" value={data.email} onChange={e=>update('email', e.target.value)}/>
          </div>

          <div style={{padding:'18px 20px',background:'var(--bg-2)',border:'1px solid var(--rule)',marginTop:8}}>
            <div style={{fontSize:11,letterSpacing:'.16em',textTransform:'uppercase',color:'var(--muted)',fontWeight:500,marginBottom:10}}>{t('依頼内容の確認', 'Request summary')}</div>
            <div style={{fontSize:13,color:'var(--ink-2)',lineHeight:1.7}}>
              <div>{t('産地', 'Origins')}: <b style={{color:'var(--ink)'}}>{data.origins.map(id => ORIGINS.find(o=>o.id===id).name[lang]).join(' · ') || '—'}</b></div>
              {data.process.length > 0 && <div>{t('精製', 'Process')}: <b style={{color:'var(--ink)'}}>{data.process.join(' · ')}</b></div>}
              <div>{t('量', 'Quantity')}: <b style={{color:'var(--ink)'}}>{data.quantity === 'small' ? t('100g 程度','~100g') : data.quantity === 'medium' ? '300g–500g' : '1kg+'}</b></div>
            </div>
          </div>
        </div>
      )}

      <div className="form-nav">
        <span className="progress">{t(`ステップ ${step+1} / ${steps.length}`, `Step ${step+1} of ${steps.length}`)}</span>
        <div className="form-nav__btns">
          {step > 0 && <button className="btn btn--ghost" onClick={()=>setStep(step-1)}>← {t('戻る','Back')}</button>}
          {step < steps.length-1 && <button className="btn btn--solid" disabled={!canNext()} onClick={()=>setStep(step+1)} style={{opacity:canNext()?1:.4}}>{t('次へ','Next')} <span className="arrow">→</span></button>}
          {step === steps.length-1 && <button className="btn btn--solid" disabled={!canNext()} onClick={submit} style={{opacity:canNext()?1:.4}}>{t('送信する','Submit')} <span className="arrow">→</span></button>}
        </div>
      </div>
    </>
  );
};

// ================== EVENT REGISTRATION ==================
const EventDetail = () => {
  const lang = useLang();
  const [open, setOpen] = useState(false);
  const [step, setStep] = useState(0);
  const [data, setData] = useState({ name:'', company:'', email:'', session:'am', count:1 });
  const [done, setDone] = useState(false);
  const t = (jp, en) => lang === 'jp' ? jp : en;
  const update = (k, v) => setData(d => ({ ...d, [k]: v }));

  return (
    <>
      <span className="eyebrow"><span data-jp>第一回 イベント</span><span data-en>Inaugural Event</span></span>
      <h2 data-jp>SCAJ2025 期間中、<br/>東京で<em>初開催。</em></h2>
      <h2 data-en>Tokyo, alongside<br/><em>SCAJ 2025.</em></h2>
      <p data-jp>初の試みとなる合同カッピング会。LinkOne 加盟5社のシグネチャーロットを、午前部・午後部の2回、計3ラウンドのカッピングで体験いただけます。</p>
      <p data-en>The first joint cupping. Five LinkOne members present their signature lots across three cupping rounds, in AM and PM sessions.</p>

      <dl className="event__meta">
        <div><dt>{t('日付','Date')}</dt><dd>2025.09.28 (Sun)</dd></div>
        <div><dt>{t('会場','Venue')}</dt><dd>UCC Coffee Academy Tokyo</dd></div>
        <div><dt>{t('時間','Time')}</dt><dd>{t('午前部 / 午後部','AM / PM Session')}</dd></div>
        <div><dt>{t('カッピング','Cuppings')}</dt><dd>{t('3 ラウンド','3 Rounds')}</dd></div>
      </dl>

      <div className="event__cta">
        <button className="btn btn--solid" onClick={()=>{setOpen(true);setStep(0);setDone(false);}}>
          {t('参加申し込み','RSVP')} <span className="arrow">→</span>
        </button>
        <a href="#sample" className="btn btn--ghost">{t('サンプルを先に依頼','Request samples first')}</a>
      </div>

      {open && (
        <div onClick={()=>setOpen(false)} style={{position:'fixed',inset:0,background:'rgba(14,13,11,.72)',zIndex:80,display:'grid',placeItems:'center',padding:'20px',backdropFilter:'blur(6px)'}}>
          <div onClick={e=>e.stopPropagation()} style={{background:'var(--bg)',maxWidth:560,width:'100%',padding:'40px 36px',position:'relative',maxHeight:'90vh',overflowY:'auto'}}>
            <button onClick={()=>setOpen(false)} style={{position:'absolute',top:14,right:14,width:32,height:32,display:'grid',placeItems:'center',color:'var(--ink-2)'}} aria-label="Close">
              <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 2l10 10M12 2L2 12" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/></svg>
            </button>

            {!done ? (
              <>
                <span className="eyebrow">RSVP · 2025.09.28</span>
                <h3 style={{fontSize:28,fontWeight:300,letterSpacing:'-.02em',margin:'12px 0 24px',lineHeight:1.1}}>{t('合同カッピング会・参加申込','Joint Cupping RSVP')}</h3>

                <div className="form-steps" style={{marginBottom:24,paddingBottom:18}}>
                  <div className={`form-step ${step===0?'active':''} ${step>0?'done':''}`}><div className="n">{step>0?'✓':1}</div><span>{t('セッション','Session')}</span></div>
                  <div className={`form-step ${step===1?'active':''}`}><div className="n">2</div><span>{t('情報','Details')}</span></div>
                </div>

                {step===0 && (
                  <>
                    <div className="field">
                      <label>{t('参加セッション','Session')} <span className="req">*</span></label>
                      <div className="checks" style={{gridTemplateColumns:'1fr 1fr'}}>
                        {[
                          {v:'am',lab:t('午前部','AM Session'),sub:'10:00 – 12:00'},
                          {v:'pm',lab:t('午後部','PM Session'),sub:'14:00 – 16:00'}
                        ].map(o => (
                          <label key={o.v} className={`check ${data.session===o.v?'on':''}`}>
                            <input type="radio" checked={data.session===o.v} onChange={()=>update('session',o.v)}/>
                            <span className="box"></span>
                            <span className="lab"><b>{o.lab}</b><span>{o.sub}</span></span>
                          </label>
                        ))}
                      </div>
                    </div>

                    <div className="field">
                      <label>{t('参加人数','Number of attendees')}</label>
                      <select value={data.count} onChange={e=>update('count', +e.target.value)}>
                        {[1,2,3,4].map(n => <option key={n} value={n}>{n} {t('名','attendee'+(n>1?'s':''))}</option>)}
                      </select>
                    </div>
                  </>
                )}

                {step===1 && (
                  <>
                    <div className="field">
                      <label>{t('会社・屋号','Company / Roastery')} <span className="req">*</span></label>
                      <input type="text" value={data.company} onChange={e=>update('company',e.target.value)}/>
                    </div>
                    <div className="field">
                      <label>{t('お名前','Name')} <span className="req">*</span></label>
                      <input type="text" value={data.name} onChange={e=>update('name',e.target.value)}/>
                    </div>
                    <div className="field">
                      <label>Email <span className="req">*</span></label>
                      <input type="email" value={data.email} onChange={e=>update('email',e.target.value)}/>
                    </div>
                  </>
                )}

                <div className="form-nav">
                  <span className="progress">{step+1} / 2</span>
                  <div className="form-nav__btns">
                    {step>0 && <button className="btn btn--ghost" onClick={()=>setStep(0)}>← {t('戻る','Back')}</button>}
                    {step===0 && <button className="btn btn--solid" onClick={()=>setStep(1)}>{t('次へ','Next')} <span className="arrow">→</span></button>}
                    {step===1 && (
                      <button className="btn btn--solid"
                        disabled={!data.name || !data.company || !data.email}
                        style={{opacity:(data.name && data.company && data.email)?1:.4}}
                        onClick={()=>{
                          // Submit to Contact Form 7 (event form) if configured
                          if (window.linkoneCF7 && window.linkoneCF7.eventFormId && window.linkoneCF7.restUrl) {
                            const form = new FormData();
                            form.append('your-company', data.company);
                            form.append('your-name', data.name);
                            form.append('your-email', data.email);
                            form.append('your-session', data.session === 'am' ? 'AM Session (10:00-12:00)' : 'PM Session (14:00-16:00)');
                            form.append('your-count', String(data.count));
                            const url = window.linkoneCF7.restUrl + 'contact-form-7/v1/contact-forms/' + window.linkoneCF7.eventFormId + '/feedback';
                            fetch(url, { method:'POST', body:form, credentials:'same-origin' })
                              .then(()=>setDone(true))
                              .catch(()=>setDone(true));
                          } else {
                            setDone(true);
                          }
                        }}>
                        {t('申し込む','Confirm RSVP')} <span className="arrow">→</span>
                      </button>
                    )}
                  </div>
                </div>
              </>
            ) : (
              <div className="form-success" style={{padding:'8px 0'}}>
                <div className="form-success__check">
                  <svg width="22" height="22" viewBox="0 0 22 22" fill="none"><path d="M5 11.5l4 4 8-9" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>
                </div>
                <h3>{t('お申込みを受付けました','RSVP confirmed')}</h3>
                <p>{t(`${data.session==='am'?'午前部':'午後部'} ・ ${data.count}名 でお席をお取りしました。詳細をメールでお送りします。`,
                       `${data.session==='am'?'AM':'PM'} session · ${data.count} attendee(s) reserved. Details sent to your email.`)}</p>
                <button className="btn btn--ghost" onClick={()=>setOpen(false)}>{t('閉じる','Close')}</button>
              </div>
            )}
          </div>
        </div>
      )}
    </>
  );
};

// ================== TWEAKS ==================
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accentColor": "#C84B1F",
  "showOrbit": true,
  "compactHero": false
}/*EDITMODE-END*/;

const Tweaks = () => {
  if(!window.useTweaks) return null;
  const [t, set] = window.useTweaks(TWEAK_DEFAULTS);

  useEffect(() => {
    document.documentElement.style.setProperty('--hi', t.accentColor);
    const orbit = document.getElementById('hero-orbit');
    if(orbit) orbit.style.display = t.showOrbit ? '' : 'none';
  }, [t]);

  const { TweaksPanel, TweakSection, TweakColor, TweakToggle } = window;
  return (
    <TweaksPanel title="Tweaks">
      <TweakSection title="Brand">
        <TweakColor label="Accent color" value={t.accentColor} onChange={v=>set('accentColor', v)}/>
      </TweakSection>
      <TweakSection title="Hero">
        <TweakToggle label="Show orbit graphic" value={t.showOrbit} onChange={v=>set('showOrbit', v)}/>
      </TweakSection>
    </TweaksPanel>
  );
};

// ================== MOUNT ==================
function mount(){
  const originRoot = document.getElementById('origin-app');
  const tabsRoot = document.getElementById('origin-tabs');
  const evRoot = document.getElementById('event-detail');
  const formRoot = document.getElementById('sample-form');

  if(originRoot){
    // Replace both origin-app and origin-tabs with single combined module that owns state
    const wrap = document.createElement('div');
    originRoot.parentNode.insertBefore(wrap, originRoot);
    originRoot.remove();
    if(tabsRoot) tabsRoot.remove();
    ReactDOM.createRoot(wrap).render(<OriginsModule/>);
  }

  if(evRoot) ReactDOM.createRoot(evRoot).render(<EventDetail/>);
  if(formRoot) ReactDOM.createRoot(formRoot).render(<SampleForm/>);

  // tweaks
  const tweakRoot = document.createElement('div');
  document.body.appendChild(tweakRoot);
  ReactDOM.createRoot(tweakRoot).render(<Tweaks/>);
}

mount();
