// Subscribe Page — JaFun 訂閱伴手禮食箱
const { useState: useStateS, useEffect: useEffectS } = React;
const SUBSCRIBE_API_BASE = window.JAFUN_AUTH_API_BASE || window.JAFUN_QUOTE_API_BASE || 'http://localhost:3001';

const PLANS = [
  { months: 12, label: 'Best Value', sub: 'お得プラン', monthly: 1380, save: 1440, total: 16560, popular: false, best: true },
  { months: 6,  label: 'Popular',    sub: '人気プラン', monthly: 1420, save: 480,  total: 8520,  popular: true,  best: false },
  { months: 3,  label: '3 個月',     sub: 'ショート',   monthly: 1450, save: 150,  total: 4350,  popular: false, best: false },
  { months: 1,  label: '嘗鮮方案',   sub: 'お試し',     monthly: 1500, save: 0,    total: 1500,  popular: false, best: false },
];

const BOX_THEMES_FALLBACK = [
  { month: '2026-08', titleJp: '盛夏', title: '花火大會', tag: '夏限定洋芋片', image: 'https://images.unsplash.com/photo-1599490659213-e2b9527bd087?w=900&q=80', description: '', items: [] },
  { month: '2026-07', titleJp: '夏', title: '夏祭典', tag: '清涼系列', image: 'https://images.unsplash.com/photo-1565958011703-44f9829ba187?w=900&q=80', description: '', items: [] },
  { month: '2026-06', titleJp: '梅雨', title: '紫陽花', tag: '梅子限定', image: 'https://images.unsplash.com/photo-1528360983277-13d401cdc186?w=900&q=80', description: '', items: [] },
  { month: '2026-05', titleJp: '初夏', title: '兒童節', tag: '柏餅・粽子', image: 'https://images.unsplash.com/photo-1607301406259-dfb186e15de8?w=900&q=80', description: '', items: [] },
  { month: '2026-04', titleJp: '春', title: '櫻花季', tag: '抹茶限定', image: 'https://images.unsplash.com/photo-1528207776546-365bb710ee93?w=900&q=80', description: '', items: [] },
];

const BOX_MONTH_NAMES = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'];

// 歷月食箱清單：後台（CMS）資料優先，新→舊排序；輪播只取最近 12 個月
function monthlyBoxList() {
  const cmsBoxes = window.MONTHLY_BOXES;
  const list = Array.isArray(cmsBoxes) && cmsBoxes.length ? cmsBoxes : BOX_THEMES_FALLBACK;
  return [...list].sort((a, b) => String(b.month).localeCompare(String(a.month)));
}

function boxMonthLabel(month) {
  const [year, monthPart] = String(month || '').split('-');
  const name = BOX_MONTH_NAMES[Number(monthPart) - 1];
  return name ? `${name} ${year}` : String(month || '');
}

function findMonthlyBox(month) {
  return monthlyBoxList().find(box => box.month === month) || null;
}

const CATEGORIES = [
  { jp: '抹茶與日本茶點', tw: '日本茶・抹茶', desc: '宇治抹茶甜點、焙茶餅乾、玄米茶包與季節限定茶飲', icon: '🍵', img: 'https://images.unsplash.com/photo-1544787219-7f47ccb76574?w=900&q=80' },
  { jp: '地域限定零食', tw: '地域スナック', desc: 'Pocky、Calbee、KitKat 與便利商店限定口味，按月份主題搭配', icon: '🍿', img: 'https://images.unsplash.com/photo-1599490659213-e2b9527bd087?w=900&q=80' },
  { jp: '和菓子伴手禮', tw: '銘菓・和菓子', desc: '京都抹茶蕨餅、琥珀糖、饅頭與各地老舖小盒裝甜點', icon: '🍡', img: 'https://images.unsplash.com/photo-1554502078-ef0fc409efce?w=900&q=80' },
  { jp: '日本拉麵與湯品', tw: 'ラーメン・汁物', desc: '人氣拉麵店監修泡麵、地域限定湯底與季節限定杯麵', icon: '🍜', img: 'https://images.unsplash.com/photo-1569718212165-3a8278d5f624?w=900&q=80' },
];

const REVIEWS = [
  { stars: 5, name: 'Lisa W.', date: '2026.04.12', text: '每個月期待開箱的心情無價，內容超豐富！上次的鬼滅限定 Pocky 在台灣根本買不到。' },
  { stars: 5, name: '小美', date: '2026.04.05', text: '訂了 6 個月方案送公司同事，每個人都好驚喜。包裝很有質感，像是真的從日本寄來的禮物。' },
  { stars: 5, name: 'Kevin C.', date: '2026.03.28', text: '當月主題是櫻花季，每樣零食都好像在京都吃到的味道。CP 值超高，已續訂第二輪。' },
  { stars: 4, name: 'Yuki', date: '2026.03.20', text: '飲品超讚，午後の紅茶台灣買不到的口味都收齊了。希望可以選不要拉麵類。' },
];

function formatSubscriptionDate(value) {
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return '';
  return `${date.getFullYear()}.${String(date.getMonth() + 1).padStart(2, '0')}.${String(date.getDate()).padStart(2, '0')}`;
}

// Mirrors the backend subscriptionSchedule(): order on/before the 3rd ships the
// 8th of that month, otherwise next month; then one box every `interval` months
// (monthly=1, bimonthly=2) for `months` boxes.
function computeShipmentSchedule(months, frequency) {
  const base = new Date();
  if (base.getDate() > 3) base.setMonth(base.getMonth() + 1);
  const interval = frequency === 'bimonthly' ? 2 : 1;
  const boxes = Math.max(1, Number(months) || 1);
  const dates = [];
  for (let i = 0; i < boxes; i += 1) {
    dates.push(new Date(base.getFullYear(), base.getMonth() + i * interval, 8));
  }
  return dates;
}

function shipmentScheduleLabels(months, frequency) {
  const dates = computeShipmentSchedule(months, frequency);
  const baseYear = dates.length ? dates[0].getFullYear() : new Date().getFullYear();
  return dates.map(d => {
    const diff = d.getFullYear() - baseYear;
    const prefix = diff === 0 ? '' : diff === 1 ? '隔年 ' : `${d.getFullYear()} 年 `;
    return `${prefix}${d.getMonth() + 1} 月 ${d.getDate()} 日`;
  });
}

function RecipientField({ label, value, onChange, placeholder }) {
  return (
    <label style={{ fontFamily: 'var(--serif)', fontSize: 13, color: 'var(--jf-mute-2)' }}>
      {label}
      <input
        value={value}
        onChange={onChange}
        placeholder={placeholder}
        style={{ width: '100%', marginTop: 8, padding: '12px 14px', border: '1px solid var(--jf-line)', background: '#fff', fontFamily: 'var(--serif)', fontSize: 14, outline: 'none', boxSizing: 'border-box' }}
      />
    </label>
  );
}

function SubscribePage({ t, onNav, authSession }) {
  const [selected, setSelected] = useStateS(0); // 12 個月 default
  const [carouselIdx, setCarouselIdx] = useStateS(0);
  const recentBoxes = monthlyBoxList().slice(0, 12);
  const [showEnterpriseForm, setShowEnterpriseForm] = useStateS(false);
  const [checkoutLoading, setCheckoutLoading] = useStateS(false);
  const [checkoutError, setCheckoutError] = useStateS('');
  const [showCheckoutForm, setShowCheckoutForm] = useStateS(false);
  const [shippingFrequency, setShippingFrequency] = useStateS('monthly');
  const [sameAsMember, setSameAsMember] = useStateS(false);
  const [addressLoading, setAddressLoading] = useStateS(false);
  const [recipient, setRecipient] = useStateS({ name: '', phone: '', postalCode: '', city: '', district: '', addressLine: '', note: '' });
  const currentSession = authSession || window.readAuthSession?.() || null;
  const plan = PLANS[selected];
  const allowsBimonthly = plan.months === 3 || plan.months === 6;
  const effectiveFrequency = allowsBimonthly ? shippingFrequency : 'monthly';
  const scheduleLabels = shipmentScheduleLabels(plan.months, effectiveFrequency);

  const subscribeRequest = window.authRequest || (async (path, options = {}) => {
    const headers = { 'Content-Type': 'application/json' };
    if (options.token) headers.Authorization = `Bearer ${options.token}`;
    const response = await fetch(`${SUBSCRIBE_API_BASE}${path}`, {
      method: options.method || 'GET',
      headers,
      body: options.body ? JSON.stringify(options.body) : undefined,
    });
    if (!response.ok) {
      const payload = await response.json().catch(() => ({}));
      throw new Error(payload.message || '目前無法建立訂閱結帳，請稍後再試。');
    }
    return response.json();
  });

  const updateRecipient = key => event => setRecipient({ ...recipient, [key]: event.target.value });

  const applyMemberAddress = async (checked) => {
    setSameAsMember(checked);
    if (!checked || !currentSession?.token) return;
    setAddressLoading(true);
    try {
      const data = await subscribeRequest('/auth/addresses', { token: currentSession.token });
      const list = Array.isArray(data) ? data : (data.addresses || []);
      const def = list.find(a => a.isDefault) || list[0];
      if (def) {
        setRecipient({
          name: def.recipientName || currentSession.user?.name || '',
          phone: def.phone || '',
          postalCode: def.postalCode || '',
          city: def.city || '',
          district: def.district || '',
          addressLine: def.addressLine || '',
          note: def.note || '',
        });
      } else {
        setRecipient(prev => ({ ...prev, name: currentSession.user?.name || prev.name }));
      }
    } catch (error) {
      setRecipient(prev => ({ ...prev, name: currentSession.user?.name || prev.name }));
    } finally {
      setAddressLoading(false);
    }
  };

  // 登入會員開啟訂閱頁時，自動帶入預設收件地址(欄位尚空才帶，不覆蓋已輸入)；與代購/結帳頁一致。
  useEffectS(() => {
    if (!currentSession?.token) return undefined;
    let cancelled = false;
    subscribeRequest('/auth/addresses', { token: currentSession.token })
      .then(data => {
        if (cancelled) return;
        const list = Array.isArray(data) ? data : (data.addresses || []);
        const def = list.find(a => a.isDefault) || list[0];
        if (!def) return;
        setRecipient(prev => (prev.name || prev.addressLine) ? prev : {
          name: def.recipientName || currentSession.user?.name || '',
          phone: def.phone || '',
          postalCode: def.postalCode || '',
          city: def.city || '',
          district: def.district || '',
          addressLine: def.addressLine || '',
          note: def.note || '',
        });
      })
      .catch(() => {});
    return () => { cancelled = true; };
  }, [currentSession?.token]);

  const openCheckoutForm = () => {
    setCheckoutError('');
    setShowCheckoutForm(true);
    setTimeout(() => document.getElementById('subscribe-checkout-form')?.scrollIntoView({ behavior: 'smooth', block: 'start' }), 50);
  };

  const checkoutPlan = async () => {
    const missing = [];
    if (!recipient.name.trim()) missing.push('收件人姓名');
    if (!recipient.phone.trim()) missing.push('手機');
    if (!recipient.city.trim()) missing.push('縣市');
    if (!recipient.postalCode.trim()) missing.push('郵遞區號');
    if (!recipient.addressLine.trim()) missing.push('詳細地址');
    if (missing.length) {
      setCheckoutError(`請填寫：${missing.join('、')}`);
      return;
    }
    // 手機號碼需為 09 開頭共 10 碼(與其他收件表單一致);超過 10 碼或格式不符請重填。
    const phoneDigits = recipient.phone.trim().replace(/\D/g, '').replace(/^886(?=9)/, '0');
    if (!/^09\d{8}$/.test(phoneDigits)) {
      setCheckoutError('電話格式不正確，請輸入 09 開頭共 10 碼的手機號碼。');
      return;
    }
    const selectedPlan = {
      ...plan,
      subscribedAt: new Date().toISOString(),
      paymentStatus: 'pending',
      checkoutMode: currentSession?.token ? 'member' : 'guest',
      memberId: currentSession?.user?.id,
      memberLinked: Boolean(currentSession?.token),
      customerEmail: '',
      shippingFrequency: effectiveFrequency,
    };
    setCheckoutLoading(true);
    setCheckoutError('');
    try {
      const payload = await subscribeRequest('/payments/stripe/subscription-checkout-sessions', {
        method: 'POST',
        token: currentSession?.token,
        body: {
          months: plan.months,
          shippingFrequency: effectiveFrequency,
          recipient: {
            name: recipient.name.trim(),
            phone: recipient.phone.trim(),
            country: 'TW',
            city: recipient.city.trim(),
            district: recipient.district.trim() || undefined,
            postalCode: recipient.postalCode.trim() || undefined,
            addressLine: recipient.addressLine.trim(),
            note: recipient.note.trim() || undefined,
          },
        },
      });
      if (!payload.url) {
        throw new Error('付款頁面建立失敗，請稍後再試。');
      }
      window.sessionStorage.setItem('jafun-subscription-plan', JSON.stringify({
        ...selectedPlan,
        ...(payload.plan || {}),
        stripeSessionId: payload.sessionId,
        memberLinked: Boolean(payload.memberLinked || currentSession?.token),
        customerEmail: payload.customerEmail || '',
      }));
      window.location.href = payload.url;
    } catch (error) {
      setCheckoutError(error.message || '訂閱結帳建立失敗，請稍後再試。');
    } finally {
      setCheckoutLoading(false);
    }
  };
  const scrollToSection = (id) => {
    document.getElementById(id)?.scrollIntoView({ behavior: 'smooth', block: 'start' });
  };

  useEffectS(() => {
    const hash = window.location.hash || '';
    const hashQuery = hash.includes('?') ? hash.slice(hash.indexOf('?') + 1) : '';
    const params = new URLSearchParams(window.location.search.replace(/^\?/, ''));
    new URLSearchParams(hashQuery).forEach((value, key) => {
      if (!params.has(key)) params.set(key, value);
    });
    if (params.get('stripe_checkout') === 'cancel') {
      setCheckoutError('訂閱付款已取消，請重新選擇方案後再結帳。');
      params.delete('stripe_checkout');
      const query = params.toString();
      window.history.replaceState(null, '', `/subscribe${query ? `?${query}` : ''}`);
    }
  }, []);

  return (
    <div data-screen-label="11 Subscribe">
      {/* HERO */}
      <section style={{ position: 'relative', minHeight: 620, background: 'var(--jf-paper-2)', overflow: 'hidden', paddingTop: 120 }}>
        <div style={{ display: 'grid', gridTemplateColumns: '1.3fr 1fr', gap: 80, maxWidth: 1280, margin: '0 auto', padding: '40px 60px', alignItems: 'center' }}>
          <div>
            <div style={{ display: 'inline-flex', alignItems: 'center', gap: 10, padding: '6px 14px', background: 'var(--jf-red)', color: '#fff', fontFamily: 'var(--sans)', fontSize: 11, letterSpacing: 3, marginBottom: 24 }}>
              MONTHLY · 月 替 わ り
            </div>
            <div className="jp" style={{ fontFamily: 'var(--serif-jp)', fontSize: 16, color: 'var(--jf-mute)', letterSpacing: 6, marginBottom: 18 }}>日本 訂閱 伴手禮 食箱</div>
            <h1 style={{ fontFamily: 'var(--serif)', fontSize: 64, lineHeight: 1.1, margin: 0, fontWeight: 500, letterSpacing: 4 }}>
              每個月<br />
              <span style={{ color: 'var(--jf-red)' }}>從日本寄來</span><br />
              一份驚喜
            </h1>
            <p style={{ fontFamily: 'var(--serif)', fontSize: 17, lineHeight: 2, color: 'var(--jf-mute-2)', marginTop: 28, maxWidth: 480 }}>
              為您精選日本美食伴手禮及當地限定零食，每月不同主題、10–12 種商品。從春櫻、夏祭、秋月到冬雪，把日本一年四季放進你家郵筒。
            </p>
            <div style={{ display: 'flex', gap: 14, marginTop: 36 }}>
              <button type="button" className="btn btn-primary" onClick={() => scrollToSection('plans')}>立即訂閱</button>
              <button type="button" className="btn btn-ghost" onClick={() => scrollToSection('contents')}>看本月內容</button>
            </div>
            <div style={{ display: 'flex', gap: 36, marginTop: 44, fontFamily: 'var(--serif)', fontSize: 13, color: 'var(--jf-mute-2)' }}>
              <div><div style={{ fontFamily: 'var(--serif)', fontSize: 28, color: 'var(--jf-ink)', fontWeight: 500 }}>10–12</div>樣商品 / 月</div>
              <div style={{ width: 1, background: 'var(--jf-line)' }} />
              <div><div style={{ fontFamily: 'var(--serif)', fontSize: 28, color: 'var(--jf-ink)', fontWeight: 500 }}>4.7<span style={{ fontSize: 14, color: 'var(--jf-mute)' }}> / 5</span></div>70+ 則評價</div>
              <div style={{ width: 1, background: 'var(--jf-line)' }} />
              <div><div style={{ fontFamily: 'var(--serif)', fontSize: 28, color: 'var(--jf-ink)', fontWeight: 500 }}>免運</div>已含日台物流</div>
            </div>
          </div>

          {/* hero box visual */}
          <div style={{ position: 'relative', height: 480 }}>
            <div style={{ position: 'absolute', top: 30, right: 0, width: 290, height: 380, background: '#fff', boxShadow: '0 30px 60px -20px rgba(0,0,0,.2)', overflow: 'hidden', transform: 'rotate(3deg)' }}>
              <img src="https://jafun.s3.ap-northeast-1.amazonaws.com/banner/box_5.png" alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} onError={(e) => e.target.src = 'https://images.unsplash.com/photo-1607301406259-dfb186e15de8?w=600&q=80'} />
            </div>
            <div style={{ position: 'absolute', top: 70, right: 170, width: 260, height: 340, background: '#fff', boxShadow: '0 30px 60px -20px rgba(0,0,0,.25)', overflow: 'hidden', transform: 'rotate(-4deg)' }}>
              <img src="https://images.unsplash.com/photo-1528207776546-365bb710ee93?w=600&q=80" alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
            </div>
            <div style={{ position: 'absolute', top: 10, right: 70, padding: '8px 14px', background: 'var(--jf-red)', color: '#fff', fontFamily: 'var(--sans)', fontSize: 10, letterSpacing: 3, transform: 'rotate(-6deg)', boxShadow: '0 6px 20px rgba(192,49,57,.4)', zIndex: 2 }}>
              APRIL · 春の便り
            </div>
            <div style={{ position: 'absolute', bottom: 0, left: 0, padding: 14, background: '#fff', fontFamily: 'var(--serif)', fontSize: 12, color: 'var(--jf-mute-2)', boxShadow: '0 10px 30px -10px rgba(0,0,0,.2)', lineHeight: 1.7, zIndex: 2 }}>
              <div style={{ fontFamily: 'var(--sans)', fontSize: 9, letterSpacing: 3, color: 'var(--jf-red)', marginBottom: 4 }}>THIS MONTH</div>
              抹茶大福 · 草莓 Pocky<br />
              櫻花拉麵 · 京都和菓子 ...
            </div>
          </div>
        </div>
      </section>

      {/* HOW IT WORKS */}
      <section className="section section-narrow" style={{ paddingTop: 100 }}>
        <div style={{ textAlign: 'center', marginBottom: 70 }}>
          <div className="jp" style={{ fontFamily: 'var(--serif-jp)', color: 'var(--jf-red)', letterSpacing: 6, marginBottom: 12 }}>サ ブ ス ク の 流 れ</div>
          <h2 style={{ fontFamily: 'var(--serif)', fontSize: 42, margin: 0, letterSpacing: 4, fontWeight: 500 }}>四步驟，等開箱</h2>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 0, position: 'relative' }}>
          {[
            ['一', '選擇方案', 'プラン', '從 1、3、6、12 個月中挑一個方案，月份越長越優惠'],
            ['二', '每月 3 號截單', '締切', '當月訂單統一於 3 號截止，安心等待'],
            ['三', '日本選品＋出貨', '出荷', '當月 8 號依序從日本倉庫出貨'],
            ['四', '收件開箱', 'お届け', '7–10 個工作天送達，期待每月驚喜'],
          ].map((s, i) => (
            <div key={i} style={{ padding: '0 30px', position: 'relative' }}>
              {i < 3 && <div style={{ position: 'absolute', top: 30, right: -1, width: 1, height: 'calc(100% - 30px)', background: 'var(--jf-line)' }} />}
              <div style={{ fontFamily: 'var(--serif-jp)', fontSize: 64, color: 'var(--jf-red)', opacity: .25, lineHeight: 1, marginBottom: 14 }}>{s[0]}</div>
              <div style={{ fontFamily: 'var(--sans)', fontSize: 11, letterSpacing: 4, color: 'var(--jf-mute)', marginBottom: 8 }}>STEP {i + 1} · {s[2]}</div>
              <h4 style={{ fontFamily: 'var(--serif)', fontSize: 22, margin: '0 0 12px', letterSpacing: 2, fontWeight: 500 }}>{s[1]}</h4>
              <p style={{ fontFamily: 'var(--serif)', fontSize: 14, color: 'var(--jf-mute-2)', lineHeight: 1.9, margin: 0 }}>{s[3]}</p>
            </div>
          ))}
        </div>
      </section>

      {/* CATEGORIES — what's inside */}
      <section id="contents" className="section section-narrow" style={{ paddingTop: 110, paddingBottom: 80 }}>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1.6fr', gap: 60, alignItems: 'start' }}>
          <div style={{ position: 'sticky', top: 100 }}>
            <div className="jp" style={{ fontFamily: 'var(--serif-jp)', color: 'var(--jf-red)', letterSpacing: 6, marginBottom: 12 }}>食 箱 の 中 身</div>
            <h2 style={{ fontFamily: 'var(--serif)', fontSize: 42, margin: '0 0 24px', letterSpacing: 4, fontWeight: 500, lineHeight: 1.2 }}>食箱裡<br />會有什麼？</h2>
            <p style={{ fontFamily: 'var(--serif)', fontSize: 15, lineHeight: 2, color: 'var(--jf-mute-2)', maxWidth: 380 }}>
              每月精選 10–12 種日本茶點、地域限定零食、和菓子伴手禮與人氣拉麵湯品。我們的選品團隊每月走訪日本各地，把當季限定、地域限定、便利商店限定的好東西收進這個盒子。
            </p>
            <div style={{ marginTop: 30, padding: 18, background: 'var(--jf-paper-2)', fontFamily: 'var(--serif)', fontSize: 13, lineHeight: 1.8, color: 'var(--jf-mute-2)' }}>
              <strong style={{ color: 'var(--jf-red)' }}>每月不重複</strong><br />
              我們承諾相鄰月份至少 80% 商品不重複，讓每次開箱都是新體驗。
            </div>
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 24 }}>
            {CATEGORIES.map((c, i) => (
              <div key={i} style={{ background: '#fff', border: '1px solid var(--jf-line)' }}>
                <div style={{ height: 200, overflow: 'hidden' }}>
                  <img src={c.img} alt={`${c.jp}：${c.desc}`} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
                </div>
                <div style={{ padding: 24 }}>
                  <div style={{ display: 'flex', alignItems: 'baseline', gap: 10, marginBottom: 10 }}>
                    <span style={{ fontFamily: 'var(--serif-jp)', fontSize: 11, color: 'var(--jf-red)', letterSpacing: 4 }}>{c.tw}</span>
                  </div>
                  <h4 style={{ fontFamily: 'var(--serif)', fontSize: 20, margin: '0 0 10px', letterSpacing: 2, fontWeight: 500 }}>{c.jp}</h4>
                  <p style={{ fontFamily: 'var(--serif)', fontSize: 13, color: 'var(--jf-mute-2)', lineHeight: 1.8, margin: 0 }}>{c.desc}</p>
                </div>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* PREVIOUS BOXES carousel */}
      <section style={{ background: 'var(--jf-ink)', color: '#fff', padding: '90px 0' }}>
        <div style={{ maxWidth: 1280, margin: '0 auto', padding: '0 60px' }}>
          <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', marginBottom: 50 }}>
            <div>
              <div className="jp" style={{ fontFamily: 'var(--serif-jp)', color: 'var(--jf-red)', letterSpacing: 6, marginBottom: 12 }}>過 去 の 食 箱</div>
              <h2 style={{ fontFamily: 'var(--serif)', fontSize: 40, margin: 0, letterSpacing: 4, fontWeight: 400, color: '#fff' }}>歷月主題回顧</h2>
            </div>
            <div style={{ display: 'flex', gap: 8 }}>
              <button aria-label="上一頁" disabled={carouselIdx <= 0} onClick={() => setCarouselIdx(Math.max(0, carouselIdx - 1))} style={{ width: 44, height: 44, border: '1px solid rgba(255,255,255,.3)', background: 'transparent', color: '#fff', cursor: 'pointer', opacity: carouselIdx <= 0 ? .35 : 1 }}>←</button>
              <button aria-label="下一頁" disabled={carouselIdx >= Math.max(0, recentBoxes.length - 3)} onClick={() => setCarouselIdx(Math.min(Math.max(0, recentBoxes.length - 3), carouselIdx + 1))} style={{ width: 44, height: 44, border: '1px solid rgba(255,255,255,.3)', background: 'transparent', color: '#fff', cursor: 'pointer', opacity: carouselIdx >= Math.max(0, recentBoxes.length - 3) ? .35 : 1 }}>→</button>
            </div>
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 20, transition: 'transform .4s' }}>
            {recentBoxes.slice(carouselIdx, carouselIdx + 3).map(box => (
              <div
                key={box.month}
                onClick={() => onNav('box', { month: box.month })}
                role="link"
                tabIndex={0}
                onKeyDown={e => e.key === 'Enter' && onNav('box', { month: box.month })}
                style={{ position: 'relative', height: 380, overflow: 'hidden', cursor: 'pointer' }}
              >
                <img src={box.image} alt={box.title} style={{ width: '100%', height: '100%', objectFit: 'cover', filter: 'brightness(.7)' }} />
                <div style={{ position: 'absolute', inset: 0, padding: 28, display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
                  <div style={{ fontFamily: 'var(--serif-jp)', fontSize: 60, color: '#fff', letterSpacing: 8, lineHeight: 1, fontWeight: 300 }}>{box.titleJp}</div>
                  <div>
                    <div style={{ fontFamily: 'var(--sans)', fontSize: 11, letterSpacing: 4, color: '#fff', opacity: .8, marginBottom: 6 }}>{boxMonthLabel(box.month)}</div>
                    <div style={{ fontFamily: 'var(--serif)', fontSize: 22, color: '#fff', letterSpacing: 2, fontWeight: 500, marginBottom: 6 }}>{box.title}</div>
                    {box.tag && <div style={{ display: 'inline-block', padding: '4px 10px', border: '1px solid rgba(255,255,255,.4)', fontFamily: 'var(--sans)', fontSize: 10, letterSpacing: 2, color: '#fff' }}>{box.tag}</div>}
                    <div style={{ marginTop: 10, fontFamily: 'var(--sans)', fontSize: 10, letterSpacing: 2, color: '#fff', opacity: .75 }}>查看本月內容 →</div>
                  </div>
                </div>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* PLANS */}
      <section id="plans" className="section section-narrow" style={{ paddingTop: 110, paddingBottom: 100 }}>
        <div style={{ textAlign: 'center', marginBottom: 60 }}>
          <div className="jp" style={{ fontFamily: 'var(--serif-jp)', color: 'var(--jf-red)', letterSpacing: 6, marginBottom: 12 }}>料 金 プ ラ ン</div>
          <h2 style={{ fontFamily: 'var(--serif)', fontSize: 42, margin: 0, letterSpacing: 4, fontWeight: 500 }}>選擇您的方案</h2>
          <p style={{ fontFamily: 'var(--serif)', fontSize: 14, color: 'var(--jf-mute-2)', marginTop: 14 }}>所有方案皆已含日本空運運費</p>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 0, border: '1px solid var(--jf-line)', background: '#fff' }}>
          {PLANS.map((p, i) => (
            <div key={i} onClick={() => setSelected(i)} style={{
              padding: '40px 24px', cursor: 'pointer', position: 'relative', textAlign: 'center',
              background: selected === i ? 'var(--jf-red)' : '#fff',
              color: selected === i ? '#fff' : 'var(--jf-ink)',
              borderRight: i < 3 ? '1px solid var(--jf-line)' : 'none',
              transition: 'all .3s',
            }}>
              {p.best && <div style={{ position: 'absolute', top: 0, left: 0, padding: '4px 12px', background: '#1a1a1a', color: '#fff', fontFamily: 'var(--sans)', fontSize: 9, letterSpacing: 3, fontWeight: 600 }}>BEST VALUE</div>}
              {p.popular && <div style={{ position: 'absolute', top: 0, left: 0, padding: '4px 12px', background: '#d4a72c', color: '#fff', fontFamily: 'var(--sans)', fontSize: 9, letterSpacing: 3, fontWeight: 600 }}>POPULAR</div>}
              <div style={{ fontFamily: 'var(--serif-jp)', fontSize: 12, letterSpacing: 4, opacity: .7, marginBottom: 8 }}>{p.sub}</div>
              <div style={{ fontFamily: 'var(--serif)', fontSize: 32, fontWeight: 500, letterSpacing: 2, marginBottom: 6 }}>{p.months} 個月</div>
              {p.save > 0 ? (
                <div style={{ fontFamily: 'var(--sans)', fontSize: 11, letterSpacing: 2, opacity: .8, marginBottom: 24 }}>節省 NT$ {p.save}</div>
              ) : (
                <div style={{ fontFamily: 'var(--sans)', fontSize: 11, letterSpacing: 2, opacity: .8, marginBottom: 24 }}>{p.label}</div>
              )}
              <div style={{ paddingTop: 20, borderTop: `1px solid ${selected === i ? 'rgba(255,255,255,.3)' : 'var(--jf-line)'}` }}>
                <div style={{ fontFamily: 'var(--serif)', fontSize: 36, fontWeight: 500 }}>NT$ {p.monthly}</div>
                <div style={{ fontFamily: 'var(--sans)', fontSize: 10, letterSpacing: 3, opacity: .7, marginTop: 4 }}>每月 / per month</div>
              </div>
              <div style={{ marginTop: 18, height: 24, display: 'grid', placeItems: 'center' }}>
                {selected === i && <div style={{ width: 24, height: 24, borderRadius: '50%', background: '#fff', display: 'grid', placeItems: 'center' }}>
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--jf-red)" strokeWidth="3"><path d="M5 12l5 5L20 7" /></svg>
                </div>}
              </div>
            </div>
          ))}
        </div>

        {/* 出貨頻率:3 / 6 個月方案可選每月或雙月,選方案當下就顯示(不必等到填收件資料才出現) */}
        {allowsBimonthly && (
          <div style={{ marginTop: 28, background: '#fff', border: '1px solid var(--jf-line)', padding: '24px 28px' }}>
            <div style={{ fontFamily: 'var(--serif)', fontSize: 16, color: 'var(--jf-ink)', marginBottom: 4 }}>選擇出貨頻率</div>
            <div style={{ fontFamily: 'var(--serif)', fontSize: 13, color: 'var(--jf-mute-2)', marginBottom: 14 }}>{plan.months} 個月方案可選擇每月或雙月出貨；雙月出貨每 2 個月寄一箱。</div>
            <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
              {[['monthly', '每月出貨'], ['bimonthly', '雙月出貨（每 2 個月）']].map(([val, label]) => (
                <button key={val} type="button" onClick={() => setShippingFrequency(val)} style={{
                  flex: '1 1 160px', padding: '12px 14px', cursor: 'pointer', fontFamily: 'var(--serif)', fontSize: 14,
                  border: `1px solid ${effectiveFrequency === val ? 'var(--jf-red)' : 'var(--jf-line)'}`,
                  background: effectiveFrequency === val ? 'var(--jf-red)' : '#fff',
                  color: effectiveFrequency === val ? '#fff' : 'var(--jf-ink)',
                }}>{label}</button>
              ))}
            </div>
          </div>
        )}

        {/* selected summary */}
        <div style={{ marginTop: 40, background: 'var(--jf-paper-2)', padding: '36px 44px', display: 'grid', gridTemplateColumns: '1fr auto', gap: 40, alignItems: 'center' }}>
          <div>
            <div style={{ fontFamily: 'var(--sans)', fontSize: 11, letterSpacing: 3, color: 'var(--jf-mute)', marginBottom: 8 }}>已選擇方案</div>
            <div style={{ fontFamily: 'var(--serif)', fontSize: 26, fontWeight: 500, letterSpacing: 2, marginBottom: 6 }}>{plan.months} 個月訂閱方案</div>
            <div style={{ fontFamily: 'var(--serif)', fontSize: 14, color: 'var(--jf-mute-2)', lineHeight: 1.8 }}>
              總價 <strong style={{ color: 'var(--jf-ink)', fontSize: 18 }}>NT$ {plan.total.toLocaleString()}</strong>
              {plan.save > 0 && <span style={{ marginLeft: 14, color: 'var(--jf-red)' }}>立馬節省 NT$ {plan.save}</span>}
              <br />
              <span style={{ fontSize: 12 }}>以上費用皆已含運費。每月 3 號截止收單，當月 8 號依序出貨。</span>
            </div>
            <div style={{ marginTop: 18, maxWidth: 520, fontFamily: 'var(--serif)', fontSize: 13, color: 'var(--jf-mute-2)', lineHeight: 1.8 }}>
              付款時填寫的 Email 會作為訂閱通知信箱。付款完成後，JaFun 會用這個 Email 寄送收據與後續出貨通知。
            </div>
          </div>
          <button className="btn btn-primary" style={{ padding: '16px 36px', fontSize: 13, minWidth: 190 }} onClick={openCheckoutForm}>
            填寫收件資料 →
          </button>
        </div>

        {checkoutError && (
          <div style={{ marginTop: 18, padding: 16, border: '1px solid var(--jf-line)', background: '#fff', color: 'var(--jf-red)', fontFamily: 'var(--serif)', fontSize: 14, lineHeight: 1.8 }}>
            {checkoutError}
          </div>
        )}

        {showCheckoutForm && (
          <div id="subscribe-checkout-form" style={{ marginTop: 28, background: '#fff', border: '1px solid var(--jf-line)', padding: '32px 36px' }}>
            <div style={{ fontFamily: 'var(--sans)', fontSize: 11, letterSpacing: 3, color: 'var(--jf-red)', marginBottom: 8 }}>收件資料與出貨</div>
            <h3 style={{ fontFamily: 'var(--serif)', fontSize: 24, margin: '0 0 24px', letterSpacing: 2, fontWeight: 500 }}>填寫收件資料</h3>

            <div style={{ marginBottom: 24, padding: 16, background: 'var(--jf-paper-2)', fontFamily: 'var(--serif)', fontSize: 14, lineHeight: 1.9, color: 'var(--jf-mute-2)' }}>
              <strong style={{ color: 'var(--jf-ink)' }}>預計出貨（共 {plan.months} 箱）</strong><br />
              {scheduleLabels.join('、')}
              <div style={{ fontSize: 12, marginTop: 6 }}>＊每月 3 號前結單、當月 8 號從日本出貨；實際到貨約 7–10 個工作天。</div>
            </div>

            {currentSession?.token && (
              <label style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 18, fontFamily: 'var(--serif)', fontSize: 14, color: 'var(--jf-mute-2)', cursor: 'pointer' }}>
                <input type="checkbox" checked={sameAsMember} onChange={e => applyMemberAddress(e.target.checked)} />
                與我的會員資料相同（自動帶入）{addressLoading ? '　載入中…' : ''}
              </label>
            )}

            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', gap: 16 }}>
              <RecipientField label="收件人姓名 *" value={recipient.name} onChange={updateRecipient('name')} placeholder="王小明" />
              <RecipientField label="手機 *" value={recipient.phone} onChange={updateRecipient('phone')} placeholder="09xxxxxxxx" />
              <RecipientField label="郵遞區號 *" value={recipient.postalCode} onChange={updateRecipient('postalCode')} placeholder="100" />
              <RecipientField label="縣市 *" value={recipient.city} onChange={updateRecipient('city')} placeholder="台北市" />
              <RecipientField label="區域" value={recipient.district} onChange={updateRecipient('district')} placeholder="中正區" />
            </div>
            <div style={{ marginTop: 16 }}>
              <RecipientField label="詳細地址 *" value={recipient.addressLine} onChange={updateRecipient('addressLine')} placeholder="○○路 ○ 段 ○ 號 ○ 樓" />
            </div>
            <div style={{ marginTop: 16 }}>
              <RecipientField label="收件備註" value={recipient.note} onChange={updateRecipient('note')} placeholder="例如：放管理室、避開上午配送" />
            </div>

            {checkoutError && (
              <div style={{ marginTop: 18, padding: 14, border: '1px solid var(--jf-line)', background: 'var(--jf-paper-2)', color: 'var(--jf-red)', fontFamily: 'var(--serif)', fontSize: 14, lineHeight: 1.8 }}>
                {checkoutError}
              </div>
            )}

            <button className="btn btn-primary" style={{ marginTop: 24, padding: '16px 36px', fontSize: 13, minWidth: 220 }} onClick={checkoutPlan} disabled={checkoutLoading}>
              {checkoutLoading ? '建立付款頁面中...' : '確認並前往信用卡結帳 →'}
            </button>
          </div>
        )}

        <div style={{ marginTop: 28, padding: 24, border: '1px dashed var(--jf-line)', fontFamily: 'var(--serif)', fontSize: 13, color: 'var(--jf-mute-2)', lineHeight: 1.9 }}>
          <strong style={{ color: 'var(--jf-ink)' }}>※ 訂閱注意事項</strong>　本頁方案為固定期數預付訂閱，付款金額會由 JaFun 依方案重新確認。期滿續訂、變更內容或取消下期安排，歡迎使用 LINE 官方帳號與我們聯繫。
        </div>
      </section>

      <EnterpriseSubscribeSection
        open={showEnterpriseForm}
        setOpen={setShowEnterpriseForm}
        onNav={onNav}
      />

      {/* REVIEWS */}
      <section style={{ background: 'var(--jf-paper-2)', padding: '90px 0' }}>
        <div style={{ maxWidth: 1280, margin: '0 auto', padding: '0 60px' }}>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 2fr', gap: 60, alignItems: 'start' }}>
            <div>
              <div className="jp" style={{ fontFamily: 'var(--serif-jp)', color: 'var(--jf-red)', letterSpacing: 6, marginBottom: 12 }}>お 客 様 の 声</div>
              <h2 style={{ fontFamily: 'var(--serif)', fontSize: 38, margin: '0 0 28px', letterSpacing: 4, fontWeight: 500 }}>訂閱者 評價</h2>
              <div style={{ fontFamily: 'var(--serif)', fontSize: 64, fontWeight: 500, color: 'var(--jf-red)', lineHeight: 1 }}>4.7</div>
              <div style={{ fontFamily: 'var(--sans)', fontSize: 12, letterSpacing: 2, color: 'var(--jf-mute)', marginTop: 6 }}>BASED ON 70 REVIEWS</div>
              <div style={{ marginTop: 18, display: 'grid', gap: 6 }}>
                {[[5, 43], [4, 20], [3, 7], [2, 0], [1, 0]].map(([s, n]) => (
                  <div key={s} style={{ display: 'grid', gridTemplateColumns: '50px 1fr 30px', gap: 10, alignItems: 'center', fontFamily: 'var(--sans)', fontSize: 11, color: 'var(--jf-mute)' }}>
                    <span>{'★'.repeat(s)}<span style={{ color: 'var(--jf-line)' }}>{'★'.repeat(5 - s)}</span></span>
                    <div style={{ height: 4, background: 'var(--jf-line)', position: 'relative' }}>
                      <div style={{ width: `${(n / 70) * 100}%`, height: '100%', background: 'var(--jf-red)' }} />
                    </div>
                    <span>{n}</span>
                  </div>
                ))}
              </div>
            </div>
            <div style={{ display: 'grid', gap: 16 }}>
              {REVIEWS.map((r, i) => (
                <div key={i} style={{ background: '#fff', padding: 28 }}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 12 }}>
                    <div>
                      <span style={{ color: '#d4a72c', letterSpacing: 1 }}>{'★'.repeat(r.stars)}</span>
                      <span style={{ color: 'var(--jf-line)', letterSpacing: 1 }}>{'★'.repeat(5 - r.stars)}</span>
                    </div>
                    <span style={{ fontFamily: 'var(--sans)', fontSize: 11, color: 'var(--jf-mute)', letterSpacing: 1 }}>{r.date}</span>
                  </div>
                  <p style={{ fontFamily: 'var(--serif)', fontSize: 15, lineHeight: 2, color: 'var(--jf-ink)', margin: '0 0 12px' }}>「{r.text}」</p>
                  <div style={{ fontFamily: 'var(--sans)', fontSize: 11, letterSpacing: 2, color: 'var(--jf-mute)' }}>— {r.name}</div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </section>

      {/* FAQ */}
      <section className="section section-narrow" style={{ paddingTop: 90, paddingBottom: 110 }}>
        <div style={{ textAlign: 'center', marginBottom: 50 }}>
          <div className="jp" style={{ fontFamily: 'var(--serif-jp)', color: 'var(--jf-red)', letterSpacing: 6, marginBottom: 12 }}>よ く あ る 質 問</div>
          <h2 style={{ fontFamily: 'var(--serif)', fontSize: 36, margin: 0, letterSpacing: 4, fontWeight: 500 }}>常見問題</h2>
        </div>
        <div style={{ maxWidth: 760, margin: '0 auto', display: 'grid', gap: 0 }}>
          {[
            ['訂閱後可以取消嗎？', '可以。系統會在下個月訂購日前寄信詢問是否續訂，您可以隨時透過 LINE 官方或會員中心取消下次續訂。已寄出商品恕不退費。'],
            ['每月寄送的商品都不一樣嗎？', '是的。我們承諾相鄰月份至少 80% 商品不重複。每月會根據當季主題（櫻花季、夏祭、秋月、冬節）挑選不同的伴手禮與限定零食。'],
            ['可以指定不要某類商品嗎？', '6 個月以上方案可在訂閱時備註過敏原（如花生、乳製品），我們會盡力替換。零食類別目前無法逐項客製，敬請見諒。'],
            ['多久會收到第一箱？', '每月 3 號截止收單、8 號依序出貨，從日本空運到台灣需 7–10 個工作天。如在月底訂購，最快可在下個月中旬收到首箱。'],
            ['可以送禮給朋友嗎？', '當然可以！結帳時填入收件人地址即可。我們會附上手寫感謝卡與精緻包裝，是非常受歡迎的生日／節日禮物選項。'],
          ].map((f, i) => (
            <FAQItem key={i} q={f[0]} a={f[1]} defaultOpen={i === 0} />
          ))}
        </div>
      </section>

      {/* FINAL CTA */}
      <section style={{ background: 'var(--jf-red)', color: '#fff', padding: '80px 0', textAlign: 'center' }}>
        <div className="jp" style={{ fontFamily: 'var(--serif-jp)', letterSpacing: 8, opacity: .8, marginBottom: 14 }}>今 月 の 食 箱 を 受 け 取 ろ う</div>
        <h2 style={{ fontFamily: 'var(--serif)', fontSize: 44, margin: '0 0 22px', letterSpacing: 4, fontWeight: 500, color: '#fff' }}>把日本，每個月寄到你家</h2>
        <p style={{ fontFamily: 'var(--serif)', fontSize: 16, opacity: .9, margin: '0 auto 36px', maxWidth: 600, lineHeight: 2 }}>從春櫻到冬雪，10–12 樣當地限定商品，4.7 星 70+ 則真實評價背書</p>
        <button type="button" className="btn" onClick={() => scrollToSection('plans')} style={{ background: '#fff', color: 'var(--jf-red)', padding: '14px 40px', fontWeight: 600 }}>立即訂閱 →</button>
      </section>
    </div>
  );
}

function EnterpriseSubscribeSection({ open, setOpen, onNav }) {
  const [done, setDone] = useStateS(false);
  const [loading, setLoading] = useStateS(false);
  const [error, setError] = useStateS('');
  const [doneMessage, setDoneMessage] = useStateS('');
  const [form, setForm] = useStateS({
    company: '',
    contact: '',
    email: '',
    phone: '',
    headcount: '',
    budget: '',
    message: '',
  });
  const inputStyle = {
    width: '100%',
    padding: '12px 14px',
    border: '1px solid var(--jf-line)',
    background: '#fff',
    fontFamily: 'var(--serif)',
    fontSize: 14,
    outline: 'none',
    boxSizing: 'border-box',
  };
  const update = key => event => setForm({ ...form, [key]: event.target.value });
  const submit = async event => {
    event.preventDefault();
    setLoading(true);
    setError('');
    setDone(false);
    setDoneMessage('');
    try {
      const response = await fetch(`${SUBSCRIBE_API_BASE}/notifications/enterprise-inquiry`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(form),
      });
      if (!response.ok) {
        let message = '目前無法送出表單，請稍後再試。';
        try {
          const payload = await response.json();
          message = Array.isArray(payload.message) ? payload.message.join('、') : (payload.message || message);
        } catch (parseError) {
          message = await response.text() || message;
        }
        throw new Error(message);
      }
      const payload = await response.json();
      setDone(true);
      setDoneMessage(payload.message || '已收到企業需求，我們會盡快與您聯繫。');
    } catch (submitError) {
      setError(submitError.message || '送出失敗，請稍後再試或改用 LINE 官方聯繫。');
    } finally {
      setLoading(false);
    }
  };

  return (
    <section className="section section-narrow" style={{ paddingTop: 0, paddingBottom: 100 }}>
      <div style={{ display: 'grid', gridTemplateColumns: '1.05fr .95fr', gap: 0, border: '1px solid var(--jf-line)', background: '#fff' }}>
        <div style={{ padding: 42 }}>
          <div className="jp" style={{ fontFamily: 'var(--serif-jp)', color: 'var(--jf-red)', letterSpacing: 6, marginBottom: 14 }}>法 人 向 け</div>
          <h2 style={{ fontFamily: 'var(--serif)', fontSize: 34, lineHeight: 1.35, letterSpacing: 3, margin: '0 0 18px', fontWeight: 500 }}>
            企業訂閱客製方案
          </h2>
          <p style={{ fontFamily: 'var(--serif)', fontSize: 15, color: 'var(--jf-mute-2)', lineHeight: 2, margin: '0 0 26px', maxWidth: 560 }}>
            JaFun 也提供企業端日本選品訂閱服務，適合員工福利、VIP 客戶贈禮、節慶禮盒、辦公室零食櫃與品牌活動。可依預算、月份、主題、收件名單與包裝需求客製內容。
          </p>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 14, marginBottom: 30 }}>
            {[
              ['01', '員工福利', '每月固定寄送日系零食與限定飲品'],
              ['02', '客戶贈禮', '可依品牌形象規劃節慶禮盒'],
              ['03', '批量配送', '支援多地址名單與出貨排程'],
            ].map(item => (
              <div key={item[0]} style={{ padding: 18, background: 'var(--jf-paper-2)', minHeight: 118 }}>
                <div style={{ fontFamily: 'var(--sans)', fontSize: 10, letterSpacing: 2, color: 'var(--jf-red)', marginBottom: 10 }}>{item[0]}</div>
                <strong style={{ display: 'block', fontFamily: 'var(--serif)', fontSize: 17, letterSpacing: 1, marginBottom: 8 }}>{item[1]}</strong>
                <div style={{ fontFamily: 'var(--serif)', fontSize: 12, color: 'var(--jf-mute-2)', lineHeight: 1.7 }}>{item[2]}</div>
              </div>
            ))}
          </div>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 12 }}>
            <button className="btn btn-line" onClick={() => window.openLineOfficial?.()}>加入 LINE 官方</button>
            <button className="btn btn-ghost" onClick={() => setOpen(!open)}>{open ? '收合表單' : '填寫企業需求表單'}</button>
          </div>
        </div>

        <div style={{ background: 'var(--jf-ink)', color: '#fff', padding: 42, display: 'grid', alignContent: 'center' }}>
          <div style={{ fontFamily: 'var(--sans)', fontSize: 11, letterSpacing: 4, color: '#d4af37', marginBottom: 16 }}>CUSTOM PLAN</div>
          <div style={{ fontFamily: 'var(--serif)', fontSize: 30, lineHeight: 1.5, letterSpacing: 2, marginBottom: 22 }}>
            依照企業預算與收件情境，規劃每月或單次日本禮盒。
          </div>
          <div style={{ display: 'grid', gap: 14, fontFamily: 'var(--serif)', fontSize: 14, color: 'rgba(255,255,255,.72)', lineHeight: 1.8 }}>
            <div>・最低建議 20 份起，可討論小量試辦</div>
            <div>・可指定日本零食、伴手禮、飲品、地方限定主題</div>
            <div>・可協助節慶卡片、品牌貼紙、分批配送</div>
          </div>
        </div>
      </div>

      {open && (
        <div style={{ marginTop: 24, background: 'var(--jf-paper-2)', border: '1px solid var(--jf-line)', padding: 34 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', gap: 20, alignItems: 'start', marginBottom: 24 }}>
            <div>
              <div style={{ fontFamily: 'var(--sans)', fontSize: 11, letterSpacing: 3, color: 'var(--jf-red)', marginBottom: 8 }}>CONTACT FORM</div>
              <h3 style={{ fontFamily: 'var(--serif)', fontSize: 26, letterSpacing: 2, margin: 0, fontWeight: 500 }}>企業需求聯絡表單</h3>
            </div>
            {done && <div style={{ fontFamily: 'var(--serif)', fontSize: 13, color: '#06c755', lineHeight: 1.7 }}>{doneMessage || '已收到企業需求，我們會盡快與您聯繫。'}</div>}
          </div>
          <form onSubmit={submit}>
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', gap: 16 }}>
              <label style={{ fontFamily: 'var(--serif)', fontSize: 13, color: 'var(--jf-mute-2)' }}>
                公司名稱
                <input value={form.company} onChange={update('company')} required placeholder="貴社名稱" style={{ ...inputStyle, marginTop: 8 }} />
              </label>
              <label style={{ fontFamily: 'var(--serif)', fontSize: 13, color: 'var(--jf-mute-2)' }}>
                聯絡人
                <input value={form.contact} onChange={update('contact')} required placeholder="王小明" style={{ ...inputStyle, marginTop: 8 }} />
              </label>
              <label style={{ fontFamily: 'var(--serif)', fontSize: 13, color: 'var(--jf-mute-2)' }}>
                Email
                <input value={form.email} onChange={update('email')} type="email" required placeholder="business@example.com" style={{ ...inputStyle, marginTop: 8 }} />
              </label>
              <label style={{ fontFamily: 'var(--serif)', fontSize: 13, color: 'var(--jf-mute-2)' }}>
                電話 / LINE ID
                <input value={form.phone} onChange={update('phone')} placeholder="可填電話或 LINE ID" style={{ ...inputStyle, marginTop: 8 }} />
              </label>
              <label style={{ fontFamily: 'var(--serif)', fontSize: 13, color: 'var(--jf-mute-2)' }}>
                預計份數
                <input value={form.headcount} onChange={update('headcount')} placeholder="例：每月 50 份" style={{ ...inputStyle, marginTop: 8 }} />
              </label>
              <label style={{ fontFamily: 'var(--serif)', fontSize: 13, color: 'var(--jf-mute-2)' }}>
                每份預算
                <input value={form.budget} onChange={update('budget')} placeholder="例：NT$ 800–1,500" style={{ ...inputStyle, marginTop: 8 }} />
              </label>
            </div>
            <label style={{ display: 'block', fontFamily: 'var(--serif)', fontSize: 13, color: 'var(--jf-mute-2)', marginTop: 16 }}>
              需求說明
              <textarea value={form.message} onChange={update('message')} required rows="5" placeholder="請描述用途、月份、主題、收件地區、是否需要品牌包裝或分批配送。" style={{ ...inputStyle, marginTop: 8, resize: 'vertical', lineHeight: 1.8 }} />
            </label>
            {error && <div style={{ marginTop: 16, padding: 14, background: '#fff', border: '1px solid var(--jf-line)', color: 'var(--jf-red)', fontFamily: 'var(--serif)', fontSize: 13, lineHeight: 1.8 }}>{error}</div>}
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 18, marginTop: 22, flexWrap: 'wrap' }}>
              <div style={{ fontFamily: 'var(--serif)', fontSize: 12, color: 'var(--jf-mute)', lineHeight: 1.8 }}>
                送出後會通知 JaFun 團隊，並寄出需求確認信到您的 Email。
              </div>
              <button className="btn btn-primary" type="submit" disabled={loading} style={{ opacity: loading ? .65 : 1 }}>{loading ? '送出中...' : '送出企業需求'}</button>
            </div>
          </form>
        </div>
      )}
    </section>
  );
}

function SubscribeSuccessPage({ t, onNav, plan, authSession }) {
  const [verifiedPlan, setVerifiedPlan] = useStateS(null);
  const [stripeNotice, setStripeNotice] = useStateS(null);
  let activePlan = verifiedPlan || plan || null;
  try {
    activePlan = activePlan || JSON.parse(window.sessionStorage.getItem('jafun-subscription-plan') || 'null');
  } catch (error) {
    activePlan = null;
  }
  activePlan = activePlan || PLANS[1];

  useEffectS(() => {
    const hash = window.location.hash || '';
    const hashQuery = hash.includes('?') ? hash.slice(hash.indexOf('?') + 1) : '';
    const params = new URLSearchParams(window.location.search.replace(/^\?/, ''));
    new URLSearchParams(hashQuery).forEach((value, key) => {
      if (!params.has(key)) params.set(key, value);
    });
    const status = params.get('stripe_checkout');
    const sessionId = params.get('session_id');
    const cleanUrl = () => {
      ['stripe_checkout', 'session_id'].forEach(key => params.delete(key));
      const query = params.toString();
      window.history.replaceState(null, '', `/subscribe-success${query ? `?${query}` : ''}`);
    };
    if (status !== 'success') return undefined;
    if (!sessionId) {
      setStripeNotice({ tone: 'error', text: '付款回傳缺少訂閱交易資訊，請聯繫客服確認。' });
      cleanUrl();
      return undefined;
    }

    let active = true;
    setStripeNotice({ tone: 'loading', text: '正在確認訂閱付款狀態...' });
    const request = window.authRequest || (async (path) => {
      const response = await fetch(`${SUBSCRIBE_API_BASE}${path}`);
      if (!response.ok) {
        const payload = await response.json().catch(() => ({}));
        throw new Error(payload.message || '目前無法確認訂閱付款，請稍後再試。');
      }
      return response.json();
    });

    request(`/payments/stripe/subscription-checkout-sessions/${encodeURIComponent(sessionId)}/confirm`)
      .then(payload => {
        if (!active) return;
        const nextPlan = {
          ...(payload.plan || {}),
          stripeSessionId: sessionId,
          paymentStatus: payload.paymentStatus,
          amountTotalTWD: payload.amountTotalTWD,
          customerEmail: payload.customerEmail,
          checkoutMode: payload.memberLinked ? 'member' : 'guest',
          memberLinked: Boolean(payload.memberLinked),
          subscription: payload.subscription,
          confirmedAt: new Date().toISOString(),
        };
        if (payload.paymentStatus === 'paid') {
          window.sessionStorage.setItem('jafun-subscription-plan', JSON.stringify(nextPlan));
          setVerifiedPlan(nextPlan);
          setStripeNotice({ tone: 'success', text: payload.memberLinked ? '訂閱付款已確認，會員中心已更新訂閱資料。' : '訂閱付款已確認，JaFun 會透過 Email 更新出貨進度。' });
        } else {
          setStripeNotice({ tone: 'error', text: '付款服務尚未回報完成，請稍後重新整理或聯繫客服確認。' });
        }
      })
      .catch(error => {
        if (!active) return;
        setStripeNotice({ tone: 'error', text: error.message || '訂閱付款確認失敗，請聯繫客服確認。' });
      })
      .finally(() => {
        if (active) cleanUrl();
      });
    return () => { active = false; };
  }, []);

  const subscription = activePlan.subscription || {};
  const isMemberSubscription = Boolean(activePlan.memberLinked || subscription.userId);
  const totalTWD = Number(subscription.totalTWD ?? activePlan.total ?? activePlan.amountTotalTWD ?? 0);
  const monthlyTWD = Number(subscription.monthlyTWD ?? activePlan.monthly ?? 0);
  const nextCutoffDate = formatSubscriptionDate(subscription.nextCutoffDate) || '每月 3 號';
  const nextShipmentDate = formatSubscriptionDate(subscription.nextShipmentDate) || '每月 8 號';
  const contactEmail = subscription.contactEmail || activePlan.customerEmail || '';

  return (
    <div data-screen-label="12 Subscribe Success">
      <section className="page-hero">
        <div className="crumb">HOME / 訂閱完成</div>
        <h1>訂閱已建立</h1>
        <div className="jp">サ ブ ス ク 完 了 · THANK YOU</div>
        <p className="desc">
          已完成 {activePlan.months} 個月日本伴手禮食箱訂閱。付款確認後，我們會建立首月出貨資料，
          {isMemberSubscription ? '並同步到會員中心方便查看。' : '並透過付款時填寫的 Email 更新進度。'}
        </p>
      </section>

      <section className="section section-narrow" style={{ paddingTop: 70 }}>
        {stripeNotice && (
          <div style={{
            marginBottom: 24,
            padding: '16px 20px',
            border: '1px solid var(--jf-line)',
            background: stripeNotice.tone === 'success' ? '#f4fbf5' : 'var(--jf-paper-2)',
            color: stripeNotice.tone === 'success' ? '#247a3b' : stripeNotice.tone === 'loading' ? 'var(--jf-mute-2)' : 'var(--jf-red)',
            fontFamily: 'var(--serif)',
            fontSize: 14,
            lineHeight: 1.8,
          }}>
            {stripeNotice.text}
          </div>
        )}
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 60, alignItems: 'start' }}>
          <div style={{ background: '#fff', border: '1px solid var(--jf-line)', padding: 34 }}>
            <div style={{ fontFamily: 'var(--sans)', fontSize: 11, letterSpacing: 3, color: '#06c755', marginBottom: 12 }}>CONFIRMED</div>
            <h2 style={{ fontFamily: 'var(--serif)', fontSize: 30, margin: '0 0 18px', letterSpacing: 2, fontWeight: 500 }}>{activePlan.months} 個月訂閱方案</h2>
            <div style={{ display: 'grid', gap: 12, fontFamily: 'var(--serif)', fontSize: 14, color: 'var(--jf-mute-2)' }}>
              <div style={{ display: 'flex', justifyContent: 'space-between' }}><span>每月金額</span><strong style={{ color: 'var(--jf-ink)' }}>NT$ {monthlyTWD.toLocaleString()}</strong></div>
              <div style={{ display: 'flex', justifyContent: 'space-between' }}><span>方案總額</span><strong style={{ color: 'var(--jf-red)' }}>NT$ {totalTWD.toLocaleString()}</strong></div>
              {contactEmail && <div style={{ display: 'flex', justifyContent: 'space-between', gap: 18 }}><span>通知 Email</span><strong style={{ color: 'var(--jf-ink)', textAlign: 'right', wordBreak: 'break-all' }}>{contactEmail}</strong></div>}
              {subscription.subscriptionNumber && <div style={{ display: 'flex', justifyContent: 'space-between' }}><span>訂閱編號</span><strong style={{ color: 'var(--jf-ink)' }}>{subscription.subscriptionNumber}</strong></div>}
              <div style={{ display: 'flex', justifyContent: 'space-between' }}><span>下次截單</span><strong style={{ color: 'var(--jf-ink)' }}>{nextCutoffDate}</strong></div>
              <div style={{ display: 'flex', justifyContent: 'space-between' }}><span>預計出貨</span><strong style={{ color: 'var(--jf-ink)' }}>{nextShipmentDate}</strong></div>
              {subscription.shippingFrequency && (
                <div style={{ display: 'flex', justifyContent: 'space-between' }}><span>出貨頻率</span><strong style={{ color: 'var(--jf-ink)' }}>{subscription.shippingFrequency === 'bimonthly' ? '雙月出貨' : '每月出貨'}</strong></div>
              )}
              {Array.isArray(subscription.shipmentSchedule) && subscription.shipmentSchedule.length > 0 && (
                <div>
                  <div style={{ marginBottom: 8 }}>出貨排程（共 {subscription.shipmentSchedule.length} 箱）</div>
                  <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
                    {subscription.shipmentSchedule.map((entry, i) => (
                      <span key={i} style={{ padding: '4px 10px', background: 'var(--jf-paper-2)', fontFamily: 'var(--serif)', fontSize: 13, color: 'var(--jf-ink)' }}>{formatSubscriptionDate(entry.shipmentDate)}</span>
                    ))}
                  </div>
                </div>
              )}
            </div>
            <div style={{ marginTop: 26, display: 'flex', gap: 10, flexWrap: 'wrap' }}>
              {isMemberSubscription ? (
                <button className="btn btn-primary" onClick={() => onNav('mypage')}>查看訂閱管理</button>
              ) : (
                <button className="btn btn-primary" onClick={() => onNav(authSession?.token ? 'mypage' : 'register')}>註冊會員</button>
              )}
              <button className="btn btn-ghost" onClick={() => onNav('learn')}>閱讀開箱指南</button>
            </div>
          </div>

          <div style={{ background: 'var(--jf-paper-2)', padding: 34 }}>
            <div className="section-eyebrow">下一步</div>
            <div style={{ display: 'grid', gap: 22, marginTop: 18 }}>
              {[
                ['01', '收據寄送', '付款完成後，電子收據會寄到付款時填寫的 Email。'],
                ['02', '建立首月資料', '付款確認後，JaFun 會建立本月食箱出貨資料。'],
                isMemberSubscription
                  ? ['03', '會員中心追蹤', '訂閱資料已同步，後續可以在會員中心查看。']
                  : ['03', '保留訂閱紀錄', '建議註冊會員，之後可在會員中心集中查看。'],
              ].map(step => (
                <div key={step[0]} style={{ display: 'grid', gridTemplateColumns: '42px 1fr', gap: 16 }}>
                  <span style={{ width: 42, height: 42, border: '1px solid var(--jf-red)', color: 'var(--jf-red)', display: 'grid', placeItems: 'center', fontFamily: 'var(--sans)', fontSize: 11, letterSpacing: 1 }}>{step[0]}</span>
                  <div>
                    <div style={{ fontFamily: 'var(--serif)', fontSize: 17, letterSpacing: 1, marginBottom: 5 }}>{step[1]}</div>
                    <div style={{ fontFamily: 'var(--serif)', fontSize: 13, color: 'var(--jf-mute-2)', lineHeight: 1.8 }}>{step[2]}</div>
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </section>
    </div>
  );
}

function FAQItem({ q, a, defaultOpen }) {
  const [open, setOpen] = useStateS(!!defaultOpen);
  return (
    <div style={{ borderBottom: '1px solid var(--jf-line)' }}>
      <div onClick={() => setOpen(!open)} style={{ padding: '22px 4px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', cursor: 'pointer', fontFamily: 'var(--serif)', fontSize: 17, fontWeight: 500, letterSpacing: 1 }}>
        <span><span style={{ color: 'var(--jf-red)', fontFamily: 'var(--serif-jp)', marginRight: 14 }}>Q</span>{q}</span>
        <span style={{ color: 'var(--jf-mute)', fontSize: 22, transform: open ? 'rotate(45deg)' : 'rotate(0deg)', transition: 'transform .25s' }}>+</span>
      </div>
      {open && (
        <div style={{ padding: '0 4px 24px 30px', fontFamily: 'var(--serif)', fontSize: 14, color: 'var(--jf-mute-2)', lineHeight: 2 }}>
          <span style={{ color: 'var(--jf-red)', fontFamily: 'var(--serif-jp)', marginRight: 14 }}>A</span>{a}
        </div>
      )}
    </div>
  );
}

function BoxDetailPage({ t, onNav, month }) {
  const boxes = monthlyBoxList();
  const index = boxes.findIndex(item => item.month === month);
  const box = index >= 0 ? boxes[index] : null;
  // boxes 為新→舊排序：上一個月＝index+1，下一個月＝index-1
  const olderBox = index >= 0 ? boxes[index + 1] : null;
  const newerBox = index > 0 ? boxes[index - 1] : null;

  useEffectS(() => {
    window.scrollTo({ top: 0 });
  }, [month]);

  if (!box) {
    return (
      <div data-screen-label="07 Box Detail">
        <section className="page-hero">
          <div className="crumb">HOME / 訂閱食箱 / 歷月主題</div>
          <h1>找不到這個月份</h1>
          <p className="desc">這個月份的食箱主題不存在或尚未發佈。</p>
        </section>
        <section className="section section-narrow" style={{ textAlign: 'center', paddingBottom: 100 }}>
          <button className="btn btn-primary" onClick={() => onNav('subscribe')}>回訂閱食箱</button>
        </section>
      </div>
    );
  }

  return (
    <div data-screen-label="07 Box Detail">
      <section style={{ position: 'relative', height: 420, overflow: 'hidden', background: 'var(--jf-ink)' }}>
        {box.image && <img src={box.image} alt={box.title} style={{ width: '100%', height: '100%', objectFit: 'cover', filter: 'brightness(.55)' }} />}
        <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', justifyContent: 'flex-end', padding: '0 60px 50px', maxWidth: 1280, margin: '0 auto', boxSizing: 'border-box', width: '100%' }}>
          <div style={{ fontFamily: 'var(--sans)', fontSize: 12, letterSpacing: 4, color: '#fff', opacity: .85, marginBottom: 10 }}>
            <span onClick={() => onNav('subscribe')} style={{ cursor: 'pointer' }}>訂閱食箱</span> / 歷月主題 / {boxMonthLabel(box.month)}
          </div>
          <h1 style={{ fontFamily: 'var(--serif)', fontSize: 46, color: '#fff', margin: '0 0 10px', letterSpacing: 3, fontWeight: 500 }}>
            {box.titleJp ? `${box.titleJp} · ` : ''}{box.title}
          </h1>
          {box.tag && <div style={{ alignSelf: 'flex-start', padding: '5px 12px', border: '1px solid rgba(255,255,255,.5)', fontFamily: 'var(--sans)', fontSize: 11, letterSpacing: 2, color: '#fff' }}>{box.tag}</div>}
        </div>
      </section>

      <section className="section section-narrow" style={{ paddingTop: 60, paddingBottom: 90 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12, marginBottom: 44 }}>
          <button
            className="btn btn-ghost"
            disabled={!olderBox}
            onClick={() => olderBox && onNav('box', { month: olderBox.month })}
            style={{ opacity: olderBox ? 1 : .4 }}
          >
            ← {olderBox ? `${boxMonthLabel(olderBox.month)} ${olderBox.title}` : '沒有更早的月份'}
          </button>
          <button
            className="btn btn-ghost"
            disabled={!newerBox}
            onClick={() => newerBox && onNav('box', { month: newerBox.month })}
            style={{ opacity: newerBox ? 1 : .4 }}
          >
            {newerBox ? `${boxMonthLabel(newerBox.month)} ${newerBox.title}` : '已是最新月份'} →
          </button>
        </div>

        {box.description && (
          <div style={{ maxWidth: 720, margin: '0 auto 50px', textAlign: 'center' }}>
            <div className="jp" style={{ fontFamily: 'var(--serif-jp)', color: 'var(--jf-red)', letterSpacing: 6, marginBottom: 14 }}>今 月 の テ ー マ</div>
            <p style={{ fontFamily: 'var(--serif)', fontSize: 16, lineHeight: 2.1, color: 'var(--jf-mute-2)', margin: 0 }}>{box.description}</p>
          </div>
        )}

        {(box.items || []).length > 0 && (
          <>
            <div style={{ textAlign: 'center', marginBottom: 30 }}>
              <h2 style={{ fontFamily: 'var(--serif)', fontSize: 30, margin: 0, letterSpacing: 3, fontWeight: 500 }}>本月內容物</h2>
              <div style={{ fontFamily: 'var(--sans)', fontSize: 11, letterSpacing: 3, color: 'var(--jf-mute)', marginTop: 8 }}>{box.items.length} ITEMS INSIDE</div>
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', gap: 16, marginBottom: 60 }}>
              {box.items.map((item, itemIndex) => (
                <div key={`${item.name}-${itemIndex}`} style={{ display: 'grid', gridTemplateColumns: '44px 1fr', gap: 14, alignItems: 'center', background: '#fff', border: '1px solid var(--jf-line)', padding: '18px 20px' }}>
                  <div style={{ fontFamily: 'var(--serif)', fontSize: 24, color: 'var(--jf-red)', fontWeight: 500 }}>{String(itemIndex + 1).padStart(2, '0')}</div>
                  <div>
                    <div style={{ fontFamily: 'var(--serif)', fontSize: 15, letterSpacing: 1 }}>{item.name}</div>
                    {item.note && <div style={{ fontFamily: 'var(--sans)', fontSize: 11, letterSpacing: 1, color: 'var(--jf-mute)', marginTop: 4 }}>{item.note}</div>}
                  </div>
                </div>
              ))}
            </div>
          </>
        )}

        <div style={{ textAlign: 'center', padding: 40, background: 'var(--jf-paper-2)' }}>
          <div style={{ fontFamily: 'var(--serif)', fontSize: 20, marginBottom: 6 }}>想收到下個月的主題食箱？</div>
          <p style={{ fontFamily: 'var(--serif)', fontSize: 13, color: 'var(--jf-mute-2)', margin: '0 0 20px' }}>每月 10–12 樣當地限定商品，含日本空運運費直送到家。</p>
          <button className="btn btn-primary" onClick={() => onNav('subscribe')}>查看訂閱方案</button>
        </div>
      </section>
    </div>
  );
}

Object.assign(window, { SubscribePage, SubscribeSuccessPage, BoxDetailPage });
