const { useState, useEffect } = React;

/* =========================================================
   v2: ヘッダー / フッター
   ========================================================= */

function SiteHeader() {
  return (
    <header className="site-header">
      <div className="site-header__inner">
        <div className="site-header__brand">
          <span className="brand-mark" aria-hidden>
            <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.4">
              <path d="M12 3c3.5 4 6 7 6 10a6 6 0 1 1-12 0c0-3 2.5-6 6-10z" />
            </svg>
          </span>
          <span className="brand-name">アクアクララ千代田</span>
        </div>
        <a className="site-header__tel" href="tel:0120074032">
          <span className="site-header__tel-label">お電話でのお申込み</span>
          <span className="site-header__tel-num">0120-074-032</span>
        </a>
      </div>
    </header>
  );
}

function SiteFooter() {
  return (
    <footer className="site-footer">
      <div className="site-footer__inner">
        <div>
          <p className="site-footer__brand">アクアクララ千代田</p>
        </div>
        <div className="site-footer__contact">
          <p className="site-footer__label">お問い合わせ</p>
          <p className="site-footer__tel">0120-074-032</p>
          <p className="site-footer__hours">平日 9:00 – 17:30</p>
        </div>
      </div>
    </footer>
  );
}

/* =========================================================
   v2: ヒーロー & プログレス
   ========================================================= */

function Hero() {
  return (
    <section className="hero">
      <p className="hero__eyebrow">Application</p>
      <h1 className="hero__title">お申込みフォーム</h1>
      <p className="hero__lede">
        ご希望の構成をお選びください。所要時間は約3分です。<br />
        送信後、担当より確認のご連絡を差し上げます。
      </p>
      <div className="hero__meta">
        <span><em>03</em> min</span><span aria-hidden>／</span>
        <span>設置費・入会金 <em>0</em> 円</span><span aria-hidden></span>
      </div>
    </section>
  );
}

function Progress({ step }) {
  const steps = [
    { n: 1, label: "プランを組む", sub: "Server / Bottle / Plan" },
    { n: 2, label: "お客様情報",   sub: "Contact" },
    { n: 3, label: "完了",         sub: "Done" },
  ];
  return (
    <nav className="progress" aria-label="進捗">
      {steps.map((s, i) => {
        const state = step > s.n ? "done" : step === s.n ? "current" : "todo";
        return (
          <React.Fragment key={s.n}>
            <div className={"progress__step is-" + state}>
              <div className="progress__dot">
                {state === "done" ? (
                  <svg viewBox="0 0 24 24" width="10" height="10" fill="none" stroke="currentColor" strokeWidth="2.4">
                    <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
                  </svg>
                ) : <span>{String(s.n).padStart(2, "0")}</span>}
              </div>
              <div className="progress__text">
                <p className="progress__label">{s.label}</p>
                <p className="progress__sub">{s.sub}</p>
              </div>
            </div>
            {i < steps.length - 1 && <div className={"progress__bar is-" + (step > s.n ? "done" : "todo")} />}
          </React.Fragment>
        );
      })}
    </nav>
  );
}

/* =========================================================
   v2: Step 1
   ========================================================= */

function StepOne({ state, set, onNext, errors }) {
  const { server, bottle, plan } = state;
  const sObj = SERVERS.find((s) => s.id === server);
  const bObj = BOTTLES.find((b) => b.id === bottle);
  const supportFee = getSupportMonthly(server, plan);
  const bottleFee  = getWaterPrice(bottle, plan);
  const kosodate   = plan === "子育てアクアプラン" ? 550 : 0;
  const monthly = supportFee !== null && bottleFee !== null ? supportFee + bottleFee * 4 - kosodate : null;
  const canProceed = server && bottle && plan;

  // ヘラルボニー選択時はプランを限定
  const allowedPlanIds = isHeralbony(server)
    ? ["2年割プラン", "子育てアクアプラン"]
    : null;
  const visiblePlans = allowedPlanIds
    ? PLANS.filter((p) => allowedPlanIds.includes(p.id))
    : PLANS;
  // 不可プランが選択中ならクリア
  useEffect(() => {
    if (allowedPlanIds && plan && !allowedPlanIds.includes(plan)) {
      set({ plan: null });
    }
  }, [server]);

  return (
    <div className="step">
      <section className="panel">
        <SectionLabel number="01" title="サーバーを選んでください" sub="設置スペースやお好みのデザインから" />
        <div className="server-grid">
          {SERVERS.map((item) => (
            <ServerCard key={item.id} item={item} selected={server === item.id} onClick={() => set({ server: item.id })} />
          ))}
        </div>
        {errors.server && <p className="field__error field__error--block">{errors.server}</p>}
      </section>

      <section className="panel">
        <SectionLabel number="02" title="ボトルサイズを選んでください" sub="ご家庭での使用量に合わせて" />
        <div className="bottle-grid">
          {BOTTLES.map((item) => (
            <BottleCard key={item.id} item={item} selected={bottle === item.id} onClick={() => set({ bottle: item.id })} />
          ))}
        </div>
        {errors.bottle && <p className="field__error field__error--block">{errors.bottle}</p>}
      </section>

      <section className="panel">
        <SectionLabel number="03" title="プランを選んでください" sub="ライフスタイルに合わせてお選びください" />
        {allowedPlanIds && (
          <p className="panel__note">
            ヘラルボニーデザインサーバーは「2年割プラン」「子育てアクアプラン」よりお選びいただけます。
          </p>
        )}
        <div className="plan-grid">
          {visiblePlans.map((item) => (
            <PlanCard key={item.id} item={item} selected={plan === item.id} onClick={() => set({ plan: item.id })} />
          ))}
        </div>
        {errors.plan && <p className="field__error field__error--block">{errors.plan}</p>}
      </section>

      <section className="panel">
        <SectionLabel number="04" title="料金プレビュー" sub="選択内容に応じて自動計算" />
        <div className="price-card">
          <div className="price-card__row">
            <div className="price-card__cell">
              <p className="price-card__label">あんしんサポート料</p>
              <p className="price-card__value">
                {supportFee !== null ? <><span>{yen(supportFee)}</span><em>円 / 月</em></> : <span className="price-card__empty">—</span>}
              </p>
              {(plan === "2年割プラン" || plan === "子育てアクアプラン") && supportFee !== null && (
                <p className="price-card__note">2年割プラン適用</p>
              )}
            </div>
            <div className="price-card__cell">
              <p className="price-card__label">お水料金（1本）</p>
              <p className="price-card__value">
                {bottleFee !== null ? <><span>{yen(bottleFee)}</span><em>円 / 本</em></> : <span className="price-card__empty">—</span>}
              </p>
              {(plan === "2年割プラン" || plan === "子育てアクアプラン") && bottleFee !== null && (
                <p className="price-card__note">割引価格適用</p>
              )}
            </div>
            <div className="price-card__cell price-card__cell--hi">
              <p className="price-card__label">月額目安<span className="price-card__tiny">（4本/月想定）</span></p>
              <p className="price-card__value">
                {monthly !== null ? <><span>{yen(monthly)}</span><em>円 / 月</em></> : <span className="price-card__empty">—</span>}
              </p>
              {plan === "子育てアクアプラン" && monthly !== null && (
                <p className="price-card__note">子育て割 −{yen(550)}円</p>
              )}
            </div>
          </div>
          {plan === "子育てアクアプラン" && (
            <div className="price-card__kosodate">
              <span className="price-card__kosodate-mark">★</span>
              子育てアクアプラン適用中は、合計金額より毎月 <strong>550円（税込）</strong> 引きとなります。
            </div>
          )}
          {!canProceed && (
            <div className="price-card__hint">
              <svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" strokeWidth="1.6">
                <circle cx="12" cy="12" r="9" /><path d="M12 8v5" strokeLinecap="round" /><circle cx="12" cy="16" r=".5" fill="currentColor" />
              </svg>
              <p>サーバー・ボトル・プランをお選びいただくと単価が表示されます。</p>
            </div>
          )}
        </div>
      </section>

      <div className="step__nav">
        <button type="button" className="btn btn--primary"
          onClick={() => canProceed && onNext()} disabled={!canProceed}>
          お客様情報の入力へ
          <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.6">
            <path strokeLinecap="round" strokeLinejoin="round" d="M9 5l7 7-7 7" />
          </svg>
        </button>
        {!canProceed && <p className="step__nav-hint">3項目すべてをご選択ください</p>}
      </div>
    </div>
  );
}

/* =========================================================
   v2: Step 2
   ========================================================= */

function StepTwo({ state, set, onBack, onSubmit, initialErrors = {} }) {
  const [errors, setErrors] = useState(initialErrors);
  const [submitting, setSubmitting] = useState(false);
  const [zipLoading, setZipLoading] = useState(false);
  const [termsOpen, setTermsOpen] = useState(false);

  const sObj = SERVERS.find((s) => s.id === state.server);
  const bObj = BOTTLES.find((b) => b.id === state.bottle);
  const pObj = PLANS.find((p) => p.id === state.plan);
  const supportFee = getSupportMonthly(state.server, state.plan);
  const bottleFee  = getWaterPrice(state.bottle, state.plan);
  const kosodate   = state.plan === "子育てアクアプラン" ? 550 : 0;

  const fetchAddress = async (zip) => {
    if (zip.length !== 7) return;
    setZipLoading(true);
    try {
      const res = await fetch(`https://zipcloud.ibsnet.co.jp/api/search?zipcode=${zip}`);
      const data = await res.json();
      if (data.results) {
        const r = data.results[0];
        set({ address: `${r.address1}${r.address2}${r.address3}` });
      }
    } catch {}
    finally { setZipLoading(false); }
  };

  const validate = () => {
    const e = {};
    if (!state.name)     e.name = "お名前をご入力ください";
    if (!state.kana)     e.kana = "フリガナをご入力ください";
    if (!state.tel)      e.tel = "電話番号をご入力ください";
    else if (!/^[0-9\-]{10,}$/.test(state.tel)) e.tel = "正しい電話番号をご入力ください";
    if (!state.email)    e.email = "メールアドレスをご入力ください";
    else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(state.email)) e.email = "メール形式が正しくありません";
    if (!state.contact_method) e.contact_method = "ご希望の連絡方法をお選びください";
    if (!state.zipcode || state.zipcode.length !== 7) e.zipcode = "7桁でご入力ください";
    if (!state.address)  e.address = "住所をご入力ください";
    else if (!/[0-9０-９一二三四五六七八九十百千]/.test(state.address)) e.address = "番地（数字）までご入力ください";
    if (!state.agree)    e.agree = "規約にご同意ください";
    return e;
  };

  const handleSubmit = async (ev) => {
    ev.preventDefault();
    const e = validate();
    setErrors(e);
    if (Object.keys(e).length) {
      const firstKey = Object.keys(e)[0];
      const el = document.querySelector(`[data-field="${firstKey}"]`);
      if (el) el.scrollIntoView({ behavior: "smooth", block: "center" });
      return;
    }
    setSubmitting(true);
    const form = document.createElement('form');
    form.method = 'POST';
    form.action = 'submit.php';
    const fields = {
      token:          window.__CSRF_TOKEN || '',
      server:         state.server        || '',
      bottle_size:    state.bottle        || '',
      plan:           state.plan          || '',
      name:           state.name          || '',
      kana:           state.kana          || '',
      company:        state.company       || '',
      tel:            state.tel           || '',
      email:          state.email         || '',
      contact_method: state.contact_method|| '',
      zipcode:        state.zipcode       || '',
      address:        state.address       || '',
      building:       state.building      || '',
      agree:          state.agree ? '1'   : '',
    };
    Object.entries(fields).forEach(([k, v]) => {
      const inp = document.createElement('input');
      inp.type = 'hidden'; inp.name = k; inp.value = v;
      form.appendChild(inp);
    });
    document.body.appendChild(form);
    sessionStorage.removeItem("apply_v2_state");
    sessionStorage.removeItem("apply_v2_step");
    form.submit();
  };

  return (
    <div className="step">
      <button type="button" className="back-link" onClick={onBack}>
        <svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" strokeWidth="1.6">
          <path strokeLinecap="round" strokeLinejoin="round" d="M15 19l-7-7 7-7" />
        </svg>
        プラン選択に戻る
      </button>

      <aside className="summary">
        <div className="summary__head">
          <p className="summary__eyebrow">Your Selection</p>
          <button type="button" className="summary__edit" onClick={onBack}>変更</button>
        </div>
        <div className="summary__tags">
          {sObj && <Tag label={sObj.name} />}
          {bObj && <Tag label={bObj.name} />}
          {pObj && <Tag label={pObj.name} />}
        </div>
        <div className="summary__prices">
          <div>
            <p className="summary__label">サポート料</p>
            <p className="summary__value">{supportFee !== null ? `${yen(supportFee)}円 / 月` : "相談"}</p>
          </div>
          <div>
            <p className="summary__label">お水料金</p>
            <p className="summary__value">{bottleFee !== null ? `${yen(bottleFee)}円 / 本` : "相談"}</p>
          </div>
          {kosodate > 0 && (
            <div>
              <p className="summary__label">子育て割</p>
              <p className="summary__value summary__value--accent">−{yen(kosodate)}円 / 月</p>
            </div>
          )}
        </div>
      </aside>

      <form onSubmit={handleSubmit} className="form" noValidate>
        <section className="panel">
          <SectionLabel number="05" title="お客様情報" sub="担当よりご連絡するための情報です" />

          <div className="form__grid form__grid--2">
            <div data-field="name">
              <FormField label="お名前" required hint="フルネームでご入力ください" error={errors.name}>
                <input type="text" className={"input " + (errors.name ? "is-error" : "")}
                  placeholder="例：山田 太郎" value={state.name}
                  onChange={(e) => set({ name: e.target.value })} maxLength={50} />
              </FormField>
            </div>
            <div data-field="kana">
              <FormField label="フリガナ" required hint="カタカナ" error={errors.kana}>
                <input type="text" className={"input " + (errors.kana ? "is-error" : "")}
                  placeholder="例：ヤマダ タロウ" value={state.kana}
                  onChange={(e) => set({ kana: e.target.value })} maxLength={80} />
              </FormField>
            </div>
          </div>

          <FormField label="法人名（法人申込の場合）" hint="法人の方のみご入力ください">
            <input type="text" className="input" placeholder="例：株式会社〇〇"
              value={state.company} onChange={(e) => set({ company: e.target.value })} maxLength={200} />
          </FormField>

          <div className="form__grid form__grid--2">
            <div data-field="tel">
              <FormField label="電話番号" required hint="ハイフンあり・なしどちらでも可" error={errors.tel}>
                <input type="tel" className={"input " + (errors.tel ? "is-error" : "")}
                  placeholder="例：03-1234-5678" value={state.tel}
                  onChange={(e) => set({ tel: e.target.value })} maxLength={20} />
              </FormField>
            </div>
            <div data-field="email">
              <FormField label="メールアドレス" required hint="受付確認メールをお送りします" error={errors.email}>
                <input type="email" className={"input " + (errors.email ? "is-error" : "")}
                  placeholder="例：info@example.com" value={state.email}
                  onChange={(e) => set({ email: e.target.value })} maxLength={254} />
              </FormField>
            </div>
          </div>

          <div data-field="contact_method">
            <FormField label="希望連絡方法" required error={errors.contact_method}>
              <div className="radio-row">
                {CONTACT_METHODS.map((v) => (
                  <label key={v} className={"radio-chip " + (state.contact_method === v ? "is-selected" : "")}>
                    <input type="radio" name="contact_method" value={v}
                      checked={state.contact_method === v}
                      onChange={() => set({ contact_method: v })} />
                    <span>{v}</span>
                  </label>
                ))}
              </div>
            </FormField>
          </div>
        </section>

        <section className="panel">
          <SectionLabel number="06" title="お届け先" sub="サーバー設置先の住所" />

          <div data-field="zipcode">
            <FormField label="郵便番号" required
              hint={zipLoading ? "住所を検索中…" : "ハイフンなし。7桁入力で住所を自動補完します"}
              error={errors.zipcode}>
              <div className="zip-row">
                <input type="text" inputMode="numeric" maxLength={7}
                  className={"input input--zip " + (errors.zipcode ? "is-error" : "")}
                  placeholder="例：1234567" value={state.zipcode}
                  onChange={(e) => {
                    const v = e.target.value.replace(/[^0-9]/g, "");
                    set({ zipcode: v });
                    if (v.length === 7) fetchAddress(v);
                  }} />
                {zipLoading && <span className="zip-row__loader" aria-hidden />}
              </div>
            </FormField>
          </div>

          <div data-field="address">
            <FormField label="住所（番地まで）" required hint="自動入力後、番地以降を追記してください" error={errors.address}>
              <input type="text" className={"input " + (errors.address ? "is-error" : "")}
                placeholder="例：東京都千代田区〇〇1-2-3" value={state.address}
                onChange={(e) => set({ address: e.target.value })} maxLength={200} />
            </FormField>
          </div>

          <FormField label="建物名・部屋番号" hint="建物名も記載いただけますと助かります">
            <input type="text" className="input" placeholder="例：〇〇ビル 3F 305"
              value={state.building} onChange={(e) => set({ building: e.target.value })} maxLength={200} />
          </FormField>
        </section>

        <section className="panel">
          <SectionLabel number="07" title="申込み規約" sub="ご一読のうえご同意ください" />
          <div className={"terms-box " + (termsOpen ? "is-open" : "")}>
            <button type="button" className="terms-box__head" onClick={() => setTermsOpen(!termsOpen)}>
              <span>規約を確認する</span>
              <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.6"
                style={{ transform: termsOpen ? "rotate(180deg)" : "none", transition: "transform .2s" }}>
                <path strokeLinecap="round" strokeLinejoin="round" d="M6 9l6 6 6-6" />
              </svg>
            </button>
            {termsOpen && (
              <div className="terms-box__body">
                <pre className="terms-box__text">{TERMS_TEXT}</pre>
              </div>
            )}
          </div>

          <div className="agree" data-field="agree">
            <label className={"agree__label " + (errors.agree ? "is-error" : "")}>
              <input type="checkbox" checked={!!state.agree}
                onChange={(e) => set({ agree: e.target.checked })} />
              <span className="agree__box" aria-hidden>
                {state.agree && (
                  <svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" strokeWidth="2.4">
                    <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
                  </svg>
                )}
              </span>
              <span className="agree__text">
                <a href="#" onClick={(e) => { e.preventDefault(); setTermsOpen(true); }}>申込み規約</a>
                および個人情報の取り扱いに同意します
                <span className="field__req field__req--inline">必須</span>
              </span>
            </label>
            {errors.agree && <p className="field__error field__error--agree">{errors.agree}</p>}
          </div>
        </section>

        <div className="submit-row">
          <button type="submit" className="btn btn--primary btn--lg" disabled={submitting}>
            {submitting ? (<><span className="spinner" aria-hidden />送信中…</>) : (
              <>申し込む
                <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.6">
                  <path strokeLinecap="round" strokeLinejoin="round" d="M9 5l7 7-7 7" />
                </svg>
              </>
            )}
          </button>
          <p className="submit-row__note">
            <strong>送信後の流れ：</strong>内容確認のうえ、担当よりご連絡します。<br />
            <strong>お電話：</strong><a href="tel:0120074032">0120-074-032</a>（平日 9:00–17:30）
          </p>
        </div>
      </form>
    </div>
  );
}

/* =========================================================
   v2: Done
   ========================================================= */

function Done({ state, onReset }) {
  const sObj = SERVERS.find((s) => s.id === state.server);
  const bObj = BOTTLES.find((b) => b.id === state.bottle);
  const pObj = PLANS.find((p) => p.id === state.plan);

  return (
    <div className="done">
      <div className="done__ring">
        <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" strokeWidth="1.2">
          <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
        </svg>
      </div>
      <p className="done__eyebrow">Application Received</p>
      <h1 className="done__title">お申込みありがとうございます</h1>
      <p className="done__lede">
        {state.name && <><strong>{state.name}</strong> 様、</>}
        内容を確認のうえ、担当者よりご連絡いたします。<br />
        通常 1〜2 営業日以内にご連絡いたします。
      </p>

      <div className="done__detail">
        <p className="done__detail-eyebrow">お申込み内容</p>
        <dl>
          {sObj && (<><dt>サーバー</dt><dd>{sObj.name}</dd></>)}
          {bObj && (<><dt>ボトル</dt><dd>{bObj.name}</dd></>)}
          {pObj && (<><dt>プラン</dt><dd>{pObj.name}</dd></>)}
          {state.email && (<><dt>メール</dt><dd>{state.email}</dd></>)}
        </dl>
      </div>

      <div className="done__card">
        <p className="done__card-label">お電話でのお問い合わせ</p>
        <p className="done__card-tel">0120-074-032</p>
        <p className="done__card-hours">平日 9:00 – 17:30</p>
      </div>

      <button type="button" className="btn btn--ghost" onClick={onReset}>トップへ戻る</button>
    </div>
  );
}

/* =========================================================
   v2: App
   ========================================================= */

const INITIAL = {
  server: null, bottle: null, plan: null,
  name: "", kana: "", company: "",
  tel: "", email: "", contact_method: "",
  zipcode: "", address: "", building: "",
  agree: false,
};

function App() {
  const [step, setStep] = useState(1);
  const [state, setState] = useState(INITIAL);

  useEffect(() => {
    // PHPバリデーションエラー後の復元（submit.php → index.php リダイレクト時）
    const phpOld = window.__FORM_OLD || {};
    if (Object.keys(phpOld).length > 0) {
      setState((s) => ({
        ...s,
        server:         phpOld.server         || s.server,
        bottle:         phpOld.bottle_size     || s.bottle,
        plan:           phpOld.plan            || s.plan,
        name:           phpOld.name            || s.name,
        kana:           phpOld.kana            || s.kana,
        company:        phpOld.company         || s.company,
        tel:            phpOld.tel             || s.tel,
        email:          phpOld.email           || s.email,
        contact_method: phpOld.contact_method  || s.contact_method,
        zipcode:        phpOld.zipcode         || s.zipcode,
        address:        phpOld.address         || s.address,
        building:       phpOld.building        || s.building,
        agree:          phpOld.agree === '1',
      }));
      setStep(window.__INIT_STEP || 1);
      return; // localStorage 復元はスキップ
    }
    try {
      const saved = JSON.parse(sessionStorage.getItem("apply_v2_state") || "null");
      const savedStep = parseInt(sessionStorage.getItem("apply_v2_step") || "1", 10);
      if (saved) setState((s) => ({ ...s, ...saved }));
      if (savedStep) setStep(savedStep);
    } catch {}
  }, []);
  useEffect(() => {
    try {
      sessionStorage.setItem("apply_v2_state", JSON.stringify(state));
      sessionStorage.setItem("apply_v2_step", String(step));
    } catch {}
  }, [state, step]);

  const set = (patch) => setState((s) => ({ ...s, ...patch }));

  const gotoStep = (n) => {
    setStep(n);
    window.scrollTo({ top: 0, behavior: "smooth" });
  };

  const handleReset = () => { setState(INITIAL); gotoStep(1); };

  return (
    <div className="page">
      <SiteHeader />
      <main className="main">
        {step < 3 && <Hero />}
        {step < 3 && <Progress step={step} />}
        {step === 1 && <StepOne state={state} set={set} onNext={() => gotoStep(2)} errors={{}} />}
        {step === 2 && <StepTwo state={state} set={set} onBack={() => gotoStep(1)} onSubmit={() => gotoStep(3)} initialErrors={window.__FORM_ERRORS || {}} />}
        {step === 3 && <Done state={state} onReset={handleReset} />}
      </main>
      <SiteFooter />
    </div>
  );
}

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
