// pages-info.jsx — Shop list, FAQ, Tokushoho, Privacy, Terms, About
const { Icon, MediaPH, PRODUCTS } = window.LCS;
const { ProductCard } = window.LCS;

// ─────────────────────────────────────────────────────────────
// SHOP LIST
// ─────────────────────────────────────────────────────────────
const ShopPage = ({ go }) => {
  return (
    <main className="page" data-screen-label="Shop">
      <div className="shell">
        <div className="page-head">
          <div>
            <div className="page-head__en">PRODUCTS</div>
            <h1>商品一覧</h1>
          </div>
          <div className="page-head__deco">{PRODUCTS.length}<span style={{ fontSize: 24 }}>title</span></div>
        </div>

        <div className="product-grid">
          {PRODUCTS.map((p) => (<ProductCard key={p.id} p={p} go={go} />))}
        </div>
      </div>
    </main>
  );
};

// ─────────────────────────────────────────────────────────────
// ABOUT (lightweight)
// ─────────────────────────────────────────────────────────────
const AboutPage = ({ go }) => (
  <main className="page" data-screen-label="About">
    <div className="shell">
      <div className="page-head">
        <div>
          <div className="page-head__en">ABOUT THE SHOP</div>
          <h1>ショップについて</h1>
        </div>
        <div className="page-head__deco">LCS</div>
      </div>

      <section className="section" style={{ marginTop: 0 }}>
        <div className="blurb">
          <div>
            <h2 className="blurb__title">社会貢献に繋がる、<br />ハンドメイド生産のカード。</h2>
            <p className="blurb__body">
              ローシスカードショップの製品づくりには、働きたくても機会に恵まれない方々の「輝ける場所」を創るという想いがあります。
            </p>
            <p className="blurb__body">
              現在は、ご縁のある身近な高齢者や障がいを持つ方々と共に、一つひとつ手作業で生産しています。
            </p>
            <p className="blurb__body">
              この活動の輪が広がることで、より多くの方が社会と繋がり、自分らしく楽しく働ける場を広げていきたいと考えています。
            </p>
          </div>
          <div className="blurb__panel">
            <div className="blurb__stat"><span className="blurb__stat-k">◆ これまでの作品数</span><span className="blurb__stat-v">6<small>タイトル</small></span></div>
            <div className="blurb__stat"><span className="blurb__stat-k">◆ 発送までの目安</span><span className="blurb__stat-v">7〜14<small>営業日</small></span></div>
            <div className="blurb__stat"><span className="blurb__stat-k">◆ 配送方法</span><span className="blurb__stat-v">クリックポスト<small> 日本郵便</small></span></div>
            <div className="blurb__stat"><span className="blurb__stat-k">◆ 送料</span><span className="blurb__stat-v">商品価格に含む</span></div>
            <div className="blurb__stat"><span className="blurb__stat-k">◆ 決済</span><span className="blurb__stat-v">Stripe<small> 各種カード対応</small></span></div>
          </div>
        </div>
      </section>

      <div className="flex gap-12 mt-32" style={{ flexWrap: "wrap" }}>
        <button className="btn btn--primary btn--lg" onClick={() => go("shop")}>商品を見る <Icon name="arrow-r" size={14} /></button>
        <button className="btn btn--lg" onClick={() => go("faq")}>よくある質問 <Icon name="chev-r" size={14} /></button>
        <button className="btn btn--lg" onClick={() => go("terms")}>利用規約 <Icon name="doc" size={14} /></button>
        <button className="btn btn--lg" onClick={() => go("privacy")}>プライバシーポリシー <Icon name="shield" size={14} /></button>
        <button className="btn btn--lg" onClick={() => go("tokushoho")}>特定商取引法に基づく表記 <Icon name="scale" size={14} /></button>
      </div>
    </div>
  </main>
);

// ─────────────────────────────────────────────────────────────
// FAQ
// ─────────────────────────────────────────────────────────────
const FAQ_DATA = [
  {
    cat: "商品について",
    items: [
      { q: "どのようなゲームを取り扱っていますか？", a: "障がい者雇用なども考慮した、ハンドメイドのカードゲームを受注生産で販売しています。パーティ向けや知育ができるカードゲームなど、さまざまなジャンルのゲームを取り扱っています。" },
      { q: "対象年齢は何歳からですか？", a: "商品ごとに対象年齢が異なります。各商品の詳細ページに「対象年齢」「プレイ人数」「プレイ時間」などの情報を掲載していますのでご確認ください。" },
      { q: "ルールは難しいですか？", a: "初めての方でも遊びやすいゲームから、じっくり考える戦略ゲームまで幅広く取り扱っています。商品ページにゲームの特徴や遊び方を掲載していますので、購入前にご確認いただけます。" },
      { q: "ルールブックは付属していますか？", a: "はい。すべての商品に、ルール説明書を閲覧できる QR コードが付属しています。そちらをスマートフォンで読み込んでご確認ください。また、商品によっては遊び方を紹介する画像も掲載しています。" },
    ],
  },
  {
    cat: "注文について",
    items: [
      { q: "会員登録は必要ですか？", a: "会員登録をしなくても商品をご購入いただけます。" },
      { q: "注文方法を教えてください。", a: "商品ページから購入ボタンを押し、決済画面に進んでください。必要な情報を入力後、ご注文を確定すると購入が完了します。" },
      { q: "注文内容を変更できますか？", a: "ご注文確定後の変更はできません。内容をよくご確認のうえご注文ください。" },
    ],
  },
  {
    cat: "お支払いについて",
    items: [
      { q: "利用できる支払い方法を教えてください。", a: "クレジットカード（Stripe 決済）がご利用いただけます。" },
      { q: "支払いはいつ行われますか？", a: "ご注文確定時に決済処理が行われます。詳しくはお使いの決済サービスにお問い合わせください。" },
      { q: "決済エラーが出た場合はどうすればいいですか？", a: "決済が正常に完了しなかった場合、ご注文は確定されません。カード情報や残高をご確認のうえ、再度ご注文手続きをお願いいたします。" },
      { q: "分割払いはできますか？", a: "分割払いの可否は、ご利用のクレジットカード会社の設定によって異なります。詳しくはカード会社へご確認ください。" },
    ],
  },
  {
    cat: "キャンセル・返品について",
    items: [
      { q: "注文のキャンセルはできますか？", a: "当サイトの商品は受注生産のため、ご注文完了（決済完了）後のキャンセルはお受けしておりません。なお、商品に破損や不良があった場合は、別途お問い合わせください。" },
      { q: "商品に不具合があった場合はどうすればいいですか？", a: "商品到着後、破損や不足があった場合はお問い合わせください。状況を確認のうえ対応いたします。" },
      { q: "お客様都合の返品はできますか？", a: "発送後の返品はお受けしておりません。なお、商品に破損や不良があった場合は、別途お問い合わせください。" },
    ],
  },
  {
    cat: "配送について",
    items: [
      {
        q: "商品の開封方法を教えてください。",
        isNew: true,
        a: () => (
          <React.Fragment>
            <p>ハサミマークがある切り取り線に沿って、カッターなどで切って開封してください。切り取り線の位置は、下記のサンプル画像をご確認ください。</p>
            <img className="faq-a__image" src="uploads/opening-cut-line-sample.png" alt="ハサミマークがある切り取り線のサンプル画像" />
          </React.Fragment>
        ),
      },
      { q: "商品はいつ発送されますか？", a: "通常、ご注文から 7〜14 営業日以内を目安に発送いたします。受注生産のため、ご注文状況や生産状況により発送時期が前後する場合があります。" },
      { q: "配送方法を教えてください。", a: "商品は日本郵便のクリックポストで発送いたします。" },
      { q: "配送料はいくらですか？", a: "配送料は全国一律 185 円です。配送料は各商品の表示価格に含まれていますので、購入手続き画面で最終金額をご確認ください。" },
      { q: "海外配送は対応していますか？", a: "現在は日本国内への配送のみ対応しています。予めご了承ください。" },
    ],
  },
  {
    cat: "クラウドファンディングについて",
    items: [
      { q: "クラウドファンディングで登録した作品の権利はどうなりますか？", a: (go) => <React.Fragment>作品の著作権その他の権利は、原則として作者または正当な権利者に帰属します。詳しくは <a onClick={() => go("terms", null, "terms-rights")} style={{ color: "var(--c-accent)", fontWeight: 700, cursor: "pointer" }}>利用規約</a> をご確認ください。</React.Fragment> },
      { q: "作品情報や画像はどの範囲で使われますか？", a: (go) => <React.Fragment>商品の制作、販売、発送、商品ページ掲載、告知、宣伝など、本サービスの提供に必要な範囲で利用します。詳しくは <a onClick={() => go("terms", null, "terms-rights")} style={{ color: "var(--c-accent)", fontWeight: 700, cursor: "pointer" }}>利用規約</a> をご確認ください。</React.Fragment> },
      { q: "他のショップで無断複製品・海賊版が販売されている場合、Lowsys Card Shopは対応してくれますか？", a: (go) => <React.Fragment>外部のショップや他社サービスで販売されている商品について、当社が販売停止の申請、法的判断、相手方との交渉などを代行することはできません。外部ショップへの削除申請や法的対応は、権利者ご本人または正当な権利者にてご対応をお願いいたします。詳しくは <a onClick={() => go("terms", null, "terms-copy-prohibition")} style={{ color: "var(--c-accent)", fontWeight: 700, cursor: "pointer" }}>利用規約</a> をご確認ください。</React.Fragment> },
      { q: "自分の作品が無断で登録・販売されている可能性がある場合はどうすればよいですか？", a: (go) => <React.Fragment><a onClick={() => go("contact")} style={{ color: "var(--c-accent)", fontWeight: 700, cursor: "pointer" }}>お問い合わせフォーム</a> よりご連絡ください。当社が必要と判断した場合、登録者への確認、資料提出の依頼、商品ページの非公開・販売停止などの措置を行うことがあります。詳しくは <a onClick={() => go("terms", null, "terms-rights-response")} style={{ color: "var(--c-accent)", fontWeight: 700, cursor: "pointer" }}>利用規約</a> をご確認ください。</React.Fragment> },
    ],
  },
];

const FAQPage = ({ go }) => {
  const [cat, setCat] = React.useState("すべて");
  const [open, setOpen] = React.useState({});

  const visible = FAQ_DATA.filter((g) => cat === "すべて" || g.cat === cat);

  return (
    <main className="page" data-screen-label="05 FAQ">
      <div className="shell">
        <div className="page-head">
          <div>
            <div className="page-head__en">FAQ · よくある質問</div>
            <h1>よくある質問</h1>
          </div>
          <div className="page-head__deco">?</div>
        </div>

        <div className="faq-cats">
          {[{ cat: "すべて" }, ...FAQ_DATA].map((g) => (
            <button key={g.cat} className={"faq-cat" + (cat === g.cat ? " active" : "")} onClick={() => setCat(g.cat)}>
              {g.cat}
              {g.isNew && <span className="badge badge--accent" style={{ marginLeft: 6 }}>NEW</span>}
            </button>
          ))}
        </div>

        {visible.map((g, gi) => (
          <section key={gi} className="mt-24">
            <h2 style={{ fontFamily: "Noto Sans JP, sans-serif", fontWeight: 900, fontSize: 22, margin: "0 0 14px", display: "flex", alignItems: "baseline", gap: 12 }}>
              <span style={{ width: 28, height: 28, background: "var(--c-main)", border: "1.5px solid var(--c-line)", borderRadius: 6, display: "inline-grid", placeItems: "center", fontFamily: "Plus Jakarta Sans, sans-serif", fontSize: 13, fontWeight: 900 }}>{gi + 1}</span>
              {g.cat}
              {g.isNew && <span className="badge badge--accent">NEW</span>}
            </h2>
            <div className="faq-list">
              {g.items.map((it, i) => {
                const key = `${gi}-${i}`;
                const isOpen = !!open[key];
                return (
                  <div key={key} className={"faq-item" + (isOpen ? " open" : "")}>
                    <button className="faq-q" onClick={() => setOpen({ ...open, [key]: !isOpen })}>
                      <span className="faq-q__q">Q</span>
                      <span className="faq-q__title">
                        {it.q}
                        {it.isNew && <span className="badge badge--accent" style={{ marginLeft: 8 }}>NEW</span>}
                      </span>
                      <span className="faq-q__chev"><Icon name="chev" size={18} /></span>
                    </button>
                    {isOpen && <div className="faq-a">{typeof it.a === "function" ? it.a(go) : it.a}</div>}
                  </div>
                );
              })}
            </div>
          </section>
        ))}

        <div className="note mt-32" style={{ marginBottom: 0 }}>
          <div className="note__icon">?</div>
          <div>
            <b>解決しない場合は</b>
            <a onClick={() => go("contact")} style={{ color: "var(--c-accent)", fontWeight: 700, cursor: "pointer" }}>お問い合わせフォーム</a> よりご連絡ください。3〜5 営業日以内にご返信いたします。
          </div>
        </div>
      </div>
    </main>
  );
};

// ─────────────────────────────────────────────────────────────
// LEGAL: shared shell
// ─────────────────────────────────────────────────────────────
const LegalShell = ({ enTitle, jpTitle, deco, sections, screen }) => {
  const sectionId = (i) => sections[i].id || `legal-sec-${screen.replace(/\s+/g, "-")}-${i}`;
  const scrollTo = (i) => {
    const el = document.getElementById(sectionId(i));
    if (!el) return;
    const header = document.querySelector(".header");
    const offset = (header ? header.getBoundingClientRect().height : 0) + 16;
    const top = el.getBoundingClientRect().top + window.scrollY - offset;
    window.scrollTo({ top, behavior: "smooth" });
  };
  React.useEffect(() => {
    if (!window.location.hash) return;
    const id = window.location.hash.slice(1);
    const i = sections.findIndex((s) => (s.id || "") === id);
    if (i < 0) return;
    window.setTimeout(() => scrollTo(i), 0);
  }, []);
  return (
    <main className="page" data-screen-label={screen}>
      <div className="shell">
        <div className="page-head">
          <div>
            <div className="page-head__en">{enTitle}</div>
            <h1>{jpTitle}</h1>
          </div>
          <div className="page-head__deco">{deco}</div>
        </div>
        <div className="legal">
          <aside className="legal__toc">
            <h4>目次</h4>
            <ol>
              {sections.map((s, i) => (
                <li key={i}>
                  <button
                    className="legal__toc-link"
                    onClick={() => scrollTo(i)}
                  >{s.title}</button>
                </li>
              ))}
            </ol>
          </aside>
          <div className="legal__body">
            {sections.map((s, i) => (
              <section key={i} id={sectionId(i)}>
                <h2>{s.title}</h2>
                {s.content}
              </section>
            ))}
          </div>
        </div>
      </div>
    </main>
  );
};

// ─────────────────────────────────────────────────────────────
// TOKUSHOHO
// ─────────────────────────────────────────────────────────────
const TokushohoPage = () => (
  <LegalShell
    screen="06 Tokushoho"
    enTitle="LEGAL / 特定商取引法に基づく表記"
    jpTitle="特定商取引法に基づく表記"
    deco="§"
    sections={[
      {
        title: "事業者情報",
        content: (
          <table className="dl-table">
            <tbody>
              <tr><th>販売事業者</th><td>株式会社ローシス（Lowsys Card Shop）</td></tr>
              <tr><th>運営責任者</th><td>宇都宮　睦大</td></tr>
              <tr><th>所在地</th><td>〒150-0045 東京都渋谷区神泉町10-15</td></tr>
              <tr><th>電話対応</th><td>電話でのサポートをご希望の場合は、お問い合わせフォームより「電話対応希望」の旨をご連絡ください。担当者より折り返しご連絡いたします。</td></tr>
              <tr><th>お問い合わせ先</th><td>商品・ご注文に関するお問い合わせは、下記お問い合わせフォームよりご連絡ください。<br /><a href="https://lcs.lowsys.co.jp/contact">https://lcs.lowsys.co.jp/contact</a><br />通常、3～5営業日以内にご返信いたします。</td></tr>
              <tr><th>サイト URL</th><td>https://lcs.lowsys.co.jp</td></tr>
            </tbody>
          </table>
        ),
      },
      {
        title: "販売価格",
        content: <p>各商品ページに記載された価格 (消費税込) によります。</p>,
      },
      {
        title: "商品代金以外の必要料金",
        content: (
          <p>商品価格はすべて税込価格です。表示されている商品価格には送料および必要な手数料が含まれており、追加料金は発生しません。</p>
        ),
      },
      {
        title: "お支払い方法",
        content: <p>クレジットカード（Stripe 決済）</p>,
      },
      {
        title: "お支払い時期",
        content: <p>クレジットカード：ご注文時に決済されます。</p>,
      },
      {
        title: "ご注文の成立時期",
        content: <p>ご注文は、当ショップにて決済の完了が確認された時点で成立するものとします。</p>,
      },
      {
        title: "商品の引渡し時期",
        content: (
          <React.Fragment>
            <p>当サイトの商品は受注生産のため、ご注文完了（決済完了）後に制作を開始いたします。</p>
            <p>通常 7〜14 営業日以内を目安に発送いたします。ただし、ご注文状況、生産状況、資材調達その他やむを得ない事情により、発送時期が前後する場合があります。</p>
          </React.Fragment>
        ),
      },
      {
        title: "配送方法",
        content: <p>日本郵便 クリックポスト。発送後の配送遅延につきましては、配送会社の事情による場合があります。</p>,
      },
      {
        title: "キャンセル・返品について",
        content: (
          <React.Fragment>
            <p>当サイトの商品は受注生産のため、ご注文完了（決済完了）後に制作を開始いたします。そのため、ご注文完了後のキャンセルおよびお客様都合による返品はお受けしておりません。</p>
            <p>商品に破損・印刷不良など、使用に支障のある問題があった場合は、商品到着後 7 日以内にお問い合わせフォームよりご連絡ください。内容を確認の上、当ショップの判断にて交換または返金等の対応を行います。返品送料は不良品の場合、当ショップが負担いたします。</p>
          </React.Fragment>
        ),
      },
      {
        title: "販売数量の制限等",
        content: <p>当サイトの商品は受注生産のため、販売期間や数量を制限する場合があります。生産状況や在庫状況により販売を停止または変更する場合があります。あらかじめご了承ください。</p>,
      },
      {
        title: "表現および商品に関する注意書き",
        content: <p>商品画像はできる限り実物に近い形で掲載しておりますが、モニター環境等により実際の色味や質感と異なって見える場合があります。</p>,
      },
      {
        title: "クーリングオフについて",
        content: <p>本サイトで販売している商品は通信販売に該当するため、特定商取引法に基づくクーリングオフ制度の適用対象外となります。</p>,
      },
    ]}
  />
);

// ─────────────────────────────────────────────────────────────
// PRIVACY
// ─────────────────────────────────────────────────────────────
const PrivacyPage = () => (
  <LegalShell
    screen="07 Privacy"
    enTitle="LEGAL / プライバシーポリシー"
    jpTitle="プライバシーポリシー"
    deco="P"
    sections={[
      { title: "はじめに", content: <p>株式会社ローシス（以下「当社」）は、当社が運営するオンラインショップ「Lowsys Card Shop」（以下「本サービス」）において、ユーザーの個人情報の重要性を認識し、以下の方針に基づき個人情報の保護に努めます。最終更新日：2026年４月１日。</p> },
      { title: "第1条（個人情報の定義）", content: <p>本ポリシーにおける「個人情報」とは、氏名、住所、電話番号、メールアドレスなど、特定の個人を識別できる情報を指します。</p> },
      { title: "第2条（個人情報の収集方法）",
        content: (
          <React.Fragment>
            <p>当社は、以下の場合にユーザーの個人情報を取得することがあります。</p>
            <ol>
              <li>商品の注文時</li>
              <li>お問い合わせフォームの利用時</li>
              <li>会員登録を行う場合</li>
              <li>アンケートやキャンペーンへの参加時</li>
            </ol>
            <p>取得する情報には、氏名・メールアドレス・住所・電話番号・配送先情報・決済に関連する情報が含まれる場合があります。なお、本サービスでは決済処理に外部決済サービスを利用しており、クレジットカード情報などの決済情報は当社では保持せず、決済サービス提供会社により安全に処理されます。</p>
          </React.Fragment>
        ) },
      { title: "第3条（個人情報の利用目的）",
        content: (
          <ol>
            <li>商品の発送およびサービス提供</li>
            <li>お問い合わせへの対応</li>
            <li>注文内容の確認および連絡</li>
            <li>サービス改善のための分析</li>
            <li>新商品やキャンペーンの案内</li>
            <li>不正利用の防止</li>
          </ol>
        ) },
      { title: "第4条（個人情報の第三者提供）",
        content: (
          <React.Fragment>
            <p>当社は、以下の場合を除き、ユーザーの同意なく第三者に個人情報を提供することはありません。</p>
            <ol>
              <li>法令に基づく場合</li>
              <li>人命または財産の保護が必要な場合</li>
              <li>商品配送、決済処理などの業務を行うため、配送業者や決済事業者などの業務委託先に必要な範囲で提供する場合</li>
            </ol>
          </React.Fragment>
        ) },
      { title: "第5条（外部サービスの利用）",
        content: (
          <React.Fragment>
            <p>本サービスでは、決済処理のために <b>Stripe</b> を利用しています。ユーザーが入力した決済情報は、Stripe のシステムを通じて安全に処理され、当社はクレジットカード情報等の決済情報を保持しません。Stripe における個人情報の取り扱いについては Stripe のプライバシーポリシー（https://stripe.com/privacy）をご確認ください。</p>
          </React.Fragment>
        ) },
      { title: "第6条（Cookie の利用）", content: <p>本サービスでは、サービス向上やアクセス解析のために Cookie を使用する場合があります。ユーザーはブラウザ設定により Cookie を無効にすることができます。</p> },
      { title: "第7条（アクセス解析ツール）", content: <p>本サービスでは、アクセス状況を分析するためのツールを利用する場合があります。これにより収集される情報には、個人を特定する情報は含まれません。</p> },
      { title: "第8条（個人情報の管理）", content: <p>当社は、個人情報の漏えい、紛失、改ざんなどを防止するため、適切な安全管理措置を講じます。</p> },
      { title: "第9条（個人情報の開示・訂正・削除）", content: <p>ユーザーは、自身の個人情報について、開示・訂正・削除を求めることができます。希望される場合は、当社のお問い合わせフォームまでご連絡ください。</p> },
      { title: "第10条（プライバシーポリシーの変更）", content: <p>当社は、必要に応じて本ポリシーを変更する場合があります。変更後のポリシーは、本サービス上に掲載された時点で効力を生じます。</p> },
      { title: "第11条（お問い合わせ窓口）", content: <p>個人情報の取り扱いに関するお問い合わせは以下までご連絡ください。<br />株式会社ローシス Lowsys Card Shop<br />お問い合わせフォーム：<a href="https://lcs.lowsys.co.jp/contact">https://lcs.lowsys.co.jp/contact</a><br />通常、3～5営業日以内にご返信いたします。</p> },
    ]}
  />
);

// ─────────────────────────────────────────────────────────────
// TERMS
// ─────────────────────────────────────────────────────────────
const TermsPage = () => (
  <LegalShell
    screen="08 Terms"
    enTitle="LEGAL / 利用規約"
    jpTitle="利用規約"
    deco="T"
    sections={[
      { title: "更新情報",
        content: (
          <React.Fragment>
            <p><span className="badge badge--accent" style={{ marginRight: 8 }}>NEW</span><b>更新日：2026年6月4日</b></p>
            <p>作品の権利および利用範囲、商品の無断複製の禁止、審査通過後の権利侵害等への対応について追記しました。</p>
            <p>主な更新内容は、Lowsys Card Shopが作品の権利を取得するサービスではないこと、作品情報・画像等の利用範囲、無断複製やデータ化の禁止、権利侵害等の疑いがある場合の対応方針です。</p>
          </React.Fragment>
        ) },
      { title: "前文", content: <p>本利用規約（以下「本規約」といいます。）は、株式会社ローシス（以下「当社」といいます。）が運営するオンラインショップ「Lowsys Card Shop」（以下「本サービス」といいます。）の利用条件を定めるものです。本サービスを利用するすべての利用者（以下「利用者」といいます。）は、本規約に同意したうえで本サービスを利用するものとします。</p> },
      { title: "第1条（適用）",
        content: (
          <ol>
            <li>本規約は、利用者と当社との間の本サービスの利用に関する一切の関係に適用されます。</li>
            <li>当社が本サービス上で掲載する各種のルール、注意事項等は、本規約の一部を構成するものとします。</li>
          </ol>
        ) },
      { title: "第2条（本サービスの内容）", content: <p>本サービスは、当社が運営するオンラインショップにおいて商品を販売するサービスです。</p> },
      { title: "第3条（売買契約の成立）",
        content: (
          <ol>
            <li>利用者が本サービスを通じて商品を注文し、決済手続きが完了した時点で売買契約が成立するものとします。</li>
            <li>当社は、以下のいずれかの事由があると判断した場合、売買契約を取り消すことができるものとします。<br />（1）利用者が本規約に違反した場合<br />（2）不正な注文または不正利用が疑われる場合<br />（3）その他、当社が売買契約の成立を適当でないと判断した場合</li>
          </ol>
        ) },
      { title: "第4条（支払方法）",
        content: (
          <ol>
            <li>本サービスにおける決済は、当社が指定する外部決済サービス（Stripe）を通じて行われます。</li>
            <li>利用者は、Stripe が提供する決済手続きに従って支払いを行うものとします。</li>
            <li>利用者と Stripe またはクレジットカード会社との間で生じたトラブルについて、当社は一切責任を負いません。</li>
          </ol>
        ) },
      { title: "第5条（商品の発送）",
        content: (
          <ol>
            <li>当社は、注文内容および支払い確認後、商品を発送します。</li>
            <li>商品は通常、注文完了後 7〜14 営業日以内を目安に発送します。</li>
            <li>注文状況、生産状況、配送事情その他の事情により、商品の発送が遅れる場合があります。</li>
            <li>商品の配送は、当社が指定する配送方法により行います。</li>
          </ol>
        ) },
      { title: "第6条（キャンセル）", content: <p>本サービスで販売される商品は受注生産のため、注文確定後のキャンセルはお受けしておりません。</p> },
      { title: "第7条（返品・交換）",
        content: (
          <ol>
            <li>商品に不良または当社の手配ミスがあった場合、当社は返品または交換にて対応します。</li>
            <li>利用者都合による返品・交換はお受けしておりません。</li>
            <li>商品はハンドメイドおよび受注生産の性質上、個体差や軽微な仕様差異が生じる場合があります。これらは不良品には該当しないものとします。</li>
          </ol>
        ) },
      { title: "第8条（購入履歴）", content: <p>本サービスでは、利用者専用の購入履歴管理機能は提供していません。利用者は、決済完了後に Stripe から送信されるレシートメール等により購入内容を確認するものとします。</p> },
      { id: "terms-rights", title: "第9条（作品の権利および利用範囲）",
        content: (
          <React.Fragment>
            <p>Lowsys Card Shopは、作品の権利を当社が取得するサービスではありません。</p>
            <p>登録作品の著作権その他の権利は、原則として作者または正当な権利者に帰属します。</p>
            <p>当社は、商品の制作、販売、発送、商品ページ掲載、告知、宣伝等、本サービスの提供に必要な範囲でのみ作品情報・画像・説明文等を利用します。</p>
            <p>アプリ化・デジタルゲーム化・映像化・出版・他社展開などを行う場合は、作者と個別に協議し、別途契約を行います。</p>
          </React.Fragment>
        ) },
      { id: "terms-copy-prohibition", title: "第10条（商品の無断複製の禁止）",
        content: (
          <React.Fragment>
            <p>利用者は本サービスの商品について、権利者または当社の許可なく、複製・スキャン・撮影・PDF化・データ化・その他これに類する行為を行い、第三者がすべての商品内容を利用できる状態で販売・配布・公開する行為を禁止します。なお、正規に購入・譲渡・贈与された商品をカードゲームとして遊ぶことや現物として譲り渡す場合はこの限りではありません。</p>
            <p>当社は、当該権利侵害等に関する法的判断、当事者間の紛争解決、代理交渉を行うものではありません。</p>
          </React.Fragment>
        ) },
      { id: "terms-rights-response", title: "第11条（審査通過後の権利侵害等への対応）",
        content: (
          <React.Fragment>
            <p>当社は作品登録の申請時に、権利侵害等がないか確認するための審査を行います。ただし、審査通過は当該作品について権利侵害がないことを保証するものではありません。</p>
            <p>審査通過後であっても、権利侵害・無断販売・不正取得・その他の疑いがあると当社が判断した場合、当社は該当商品ページの非公開・販売停止・売上金の支払保留・登録削除・その他必要な措置を行うことができます。</p>
            <p>また、当社が必要と判断した場合、登録者に対して権利処理に関する確認、資料の提出または該当商品の修正・差替えを求める場合があります。</p>
            <p>ただし、当社が悪質または重大と判断した場合、事前の確認または要請を行わずに必要な措置を講じることができます。</p>
          </React.Fragment>
        ) },
      { title: "第12条（禁止事項）",
        content: (
          <React.Fragment>
            <p>利用者は、本サービスの利用にあたり、以下の行為をしてはなりません。</p>
            <ol>
              <li>法令または公序良俗に違反する行為</li>
              <li>犯罪行為に関連する行為</li>
              <li>本サービスの運営を妨害する行為</li>
              <li>不正アクセスまたはこれを試みる行為</li>
              <li>他の利用者または第三者に不利益、損害、不快感を与える行為</li>
              <li>不正な注文または決済の試み</li>
              <li>その他、当社が不適切と判断する行為</li>
            </ol>
          </React.Fragment>
        ) },
      { title: "第13条（免責事項）",
        content: (
          <ol>
            <li>当社は、本サービスに事実上または法律上の瑕疵（安全性、信頼性、正確性、完全性、有効性、特定目的への適合性など）を含まないことを保証するものではありません。</li>
            <li>当社は、本サービスの利用により利用者に生じた損害について、一切の責任を負いません。</li>
            <li>当社は、配送遅延、通信障害、天災その他の不可抗力により生じた損害について責任を負いません。</li>
          </ol>
        ) },
      { title: "第14条（サービス内容の変更等）", content: <p>当社は、利用者に通知することなく、本サービスの内容を変更、停止または終了することができます。</p> },
      { title: "第15条（利用規約の変更）", content: <p>当社は、必要と判断した場合、利用者に通知することなく本規約を変更することができます。変更後の規約は、本サービス上に掲載した時点から効力を生じるものとします。</p> },
      { title: "第16条（準拠法および管轄）",
        content: (
          <ol>
            <li>本規約の解釈には日本法を準拠法とします。</li>
            <li>本サービスに関して紛争が生じた場合、当社の所在地を管轄する裁判所を専属的合意管轄とします。</li>
          </ol>
        ) },
      { title: "制定日", content: <p>制定日：2026年４月１日<br />運営者：株式会社ローシス<br />ショップ名：Lowsys Card Shop</p> },
    ]}
  />
);

// ─────────────────────────────────────────────────────────────
// CONTACT
// ─────────────────────────────────────────────────────────────
// EmailJS のメール送信は /api/contact の Pages Function が行う。
// Cloudflare Turnstile: https://dash.cloudflare.com/ → Turnstile → サイト追加
const TURNSTILE_SITE_KEY  = "0x4AAAAAADWo2Uryy7SI0EZv"; // Cloudflare → Turnstile → サイトキー

const CONTACT_CATEGORIES = [
  "購入後や配送に関するお問い合わせ",
  "初期不良に関するお問い合わせ",
  "購入前・商品やショップに関する質問",
  "クラウドファンディングについて",
  "電話対応希望",
  "その他",
];
const CATEGORIES_REQUIRING_RECEIPT = [
  "購入後や配送に関するお問い合わせ",
  "初期不良に関するお問い合わせ",
];
const INITIAL_DEFECT_CATEGORY = "初期不良に関するお問い合わせ";
const MAX_DEFECT_IMAGES = 3;
const MAX_DEFECT_IMAGE_SIZE = 5 * 1024 * 1024;

const CONTACT_INIT = {
  name: "", furigana: "", email: "", category: "", orderNo: "", phoneNumber: "", message: "", defectAgreement: false, defectImages: [], agreed: false,
};

const validateContact = ({ name, furigana, email, category, orderNo, phoneNumber, message, defectAgreement, defectImages, agreed }) => {
  const err = {};
  if (!name.trim()) err.name = "お名前を入力してください。";
  if (!furigana.trim()) err.furigana = "フリガナを入力してください。";
  if (!email.trim()) err.email = "メールアドレスを入力してください。";
  else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.trim())) err.email = "正しいメールアドレスを入力してください。";
  if (!category) err.category = "お問い合わせ種別を選択してください。";
  if (CATEGORIES_REQUIRING_RECEIPT.includes(category) && !orderNo.trim()) err.orderNo = "領収書番号を入力してください。";
  if (category === "電話対応希望" && !phoneNumber.trim()) err.phoneNumber = "電話番号を入力してください。";
  if (category === INITIAL_DEFECT_CATEGORY) {
    if (!defectAgreement) err.defectAgreement = "内容をご確認のうえチェックしてください。";
    if (!defectImages.length) err.defectImages = "商品の状態がわかる写真を添付してください。";
  }
  if (!message.trim()) err.message = "お問い合わせ内容を入力してください。";
  else if (message.trim().length < 10) err.message = "10文字以上でご記入ください。";
  if (!agreed) err.agreed = "プライバシーポリシーへの同意が必要です。";
  return err;
};

const ContactPage = ({ go }) => {
  const [sent, setSent] = React.useState(false);
  const [isSubmitting, setIsSubmitting] = React.useState(false);
  const [errors, setErrors] = React.useState({});
  const [submitError, setSubmitError] = React.useState("");
  const [turnstileToken, setTurnstileToken] = React.useState(null);
  const [touched, setTouched] = React.useState({});
  const turnstileRef = React.useRef(null);
  const widgetIdRef = React.useRef(null);
  const [f, setF] = React.useState(CONTACT_INIT);
  const set = (k, v) => setF((prev) => ({ ...prev, [k]: v }));
  const touch = (k) => setTouched((prev) => ({ ...prev, [k]: true }));
  const setCategory = (category) => setF((prev) => ({
    ...prev,
    category,
    orderNo: CATEGORIES_REQUIRING_RECEIPT.includes(category) ? prev.orderNo : "",
    phoneNumber: category === "電話対応希望" ? prev.phoneNumber : "",
    defectAgreement: category === INITIAL_DEFECT_CATEGORY ? prev.defectAgreement : false,
    defectImages: category === INITIAL_DEFECT_CATEGORY ? prev.defectImages : [],
  }));
  const setDefectImages = async (files) => {
    const selected = Array.from(files).slice(0, MAX_DEFECT_IMAGES);
    const invalid = selected.find((file) => !file.type.startsWith("image/") || file.size > MAX_DEFECT_IMAGE_SIZE);
    touch("defectImages");
    if (invalid) {
      setF((prev) => ({ ...prev, defectImages: [] }));
      setErrors((prev) => ({
        ...prev,
        defectImages: "画像ファイルを選択してください。添付は3枚まで、1枚あたり5MB以内です。",
      }));
      return;
    }
    const images = await Promise.all(selected.map((file) => new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = () => resolve({
        name: file.name,
        type: file.type,
        size: file.size,
        data: reader.result,
      });
      reader.onerror = reject;
      reader.readAsDataURL(file);
    })));
    setErrors((prev) => {
      const next = { ...prev };
      delete next.defectImages;
      return next;
    });
    setF((prev) => ({ ...prev, defectImages: images }));
  };
  const showReceiptNumber = CATEGORIES_REQUIRING_RECEIPT.includes(f.category);
  const showPhoneNumber = f.category === "電話対応希望";
  const showInitialDefectFields = f.category === INITIAL_DEFECT_CATEGORY;
  const validationErrors = validateContact(f);
  const visibleErrors = Object.keys(validationErrors).reduce((shown, key) => {
    if (touched[key] || errors[key]) shown[key] = validationErrors[key];
    return shown;
  }, {});
  const isFormValid = Object.keys(validationErrors).length === 0;

  React.useEffect(() => {
    if (sent) return;
    const render = () => {
      if (!turnstileRef.current || !window.turnstile) return;
      widgetIdRef.current = window.turnstile.render(turnstileRef.current, {
        sitekey: TURNSTILE_SITE_KEY,
        callback: (token) => setTurnstileToken(token),
        "expired-callback": () => setTurnstileToken(null),
        "error-callback": () => setTurnstileToken(null),
        theme: "light",
      });
    };
    if (window.turnstile) {
      render();
    } else {
      window.__turnstileQueue = window.__turnstileQueue || [];
      window.__turnstileQueue.push(render);
    }
    return () => {
      if (widgetIdRef.current != null && window.turnstile) {
        window.turnstile.remove(widgetIdRef.current);
        widgetIdRef.current = null;
      }
    };
  }, [sent]);

  const handleSubmit = async (e) => {
    e.preventDefault();
    const errs = validateContact(f);
    if (Object.keys(errs).length) { setErrors(errs); return; }
    if (!turnstileToken) {
      setSubmitError("セキュリティ確認が完了していません。しばらく待ってから再試行してください。");
      return;
    }
    setErrors({});
    setSubmitError("");
    setIsSubmitting(true);
    try {
      const response = await fetch("/api/contact", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ ...f, turnstileToken }),
      });
      const result = await response.json().catch(() => ({}));
      if (!response.ok) {
        throw new Error(result.message || "送信に失敗しました。時間をおいてもう一度お試しください。");
      }
      setSent(true);
      window.scrollTo({ top: 0, behavior: "smooth" });
    } catch (error) {
      setTurnstileToken(null);
      if (widgetIdRef.current != null && window.turnstile) {
        window.turnstile.reset(widgetIdRef.current);
      }
      setSubmitError(error.message || "送信に失敗しました。時間をおいてもう一度お試しください。");
    } finally {
      setIsSubmitting(false);
    }
  };

  const resetForm = () => {
    setF(CONTACT_INIT);
    setErrors({});
    setTouched({});
    setSubmitError("");
    setTurnstileToken(null);
    setSent(false);
    window.scrollTo({ top: 0, behavior: "instant" });
  };

  return (
    <main className="page">
      <div className="shell">
        <div className="page-head">
          <div>
            <div className="page-head__en">CONTACT</div>
            <h1>お問い合わせ</h1>
          </div>
          <div className="page-head__deco">?</div>
        </div>

        <div className="contact-grid">

          {/* ── サイドカード ── */}
          <aside className="contact-side">
            <h3>お問い合わせの前に</h3>
            <p>
              ご質問の多くは、{" "}
              <a onClick={() => go("faq")} style={{ color: "var(--c-accent)", fontWeight: 700, cursor: "pointer" }}>よくある質問</a>
              {" "}ページにて回答しています。<br />
              あわせてご確認ください。
            </p>
            <div className="contact-side__item">
              <b><Icon name="info" size={14} /> 営業時間</b>
              <span>平日 10:00 — 18:00 (土日祝休)</span>
            </div>
            <div className="contact-side__item">
              <b><Icon name="card" size={14} /> 購入後や配送に関するお問い合わせ</b>
              <span>領収書番号 XXXX-XXXX を添えてご連絡ください。</span>
            </div>
            <div className="note mt-16" style={{ marginBottom: 0 }}>
              <div className="note__icon">!</div>
              <div>
                <b>返信について</b>
                通常 3〜5 営業日以内にご返信します。返信が来ない場合は、メール受信設定をご確認のうえ再送ください。
              </div>
            </div>
          </aside>

          {/* ── メインカラム ── */}
          {sent ? (
            <div className="contact-form" role="status" aria-live="polite" style={{ textAlign: "center", padding: "64px" }}>
              <div className="complete__seal" style={{ width: 80, height: 80, margin: "0 auto 20px" }}>
                <Icon name="check" size={36} />
              </div>
              <h2 style={{ fontFamily: "Noto Sans JP, sans-serif", fontWeight: 900, fontSize: 24, margin: "0 0 8px" }}>
                送信しました
              </h2>
              <p style={{ color: "var(--c-ink-2)", fontSize: 14, lineHeight: 1.8 }}>
                お問い合わせありがとうございます。<br />
                3〜5 営業日以内にご返信いたします。
              </p>
              <button className="btn mt-24" onClick={resetForm}>新しい問い合わせを送る</button>
            </div>
          ) : (
            <form className="contact-form" onSubmit={handleSubmit} noValidate>

              {/* お名前 / フリガナ */}
              <div className="field__row">
                <div className="field">
                  <label htmlFor="cf-name">
                    お名前 <span className="req" aria-hidden="true">必須</span>
                  </label>
                  <input
                    id="cf-name"
                    type="text"
                    placeholder="例: 山田 太郎"
                    value={f.name}
                    onChange={(e) => set("name", e.target.value)}
                    onBlur={() => touch("name")}
                    aria-required="true"
                    aria-invalid={!!visibleErrors.name}
                  />
                  {visibleErrors.name && <span className="field__err" role="alert">{visibleErrors.name}</span>}
                </div>
                <div className="field">
                  <label htmlFor="cf-furigana">
                    お名前 (フリガナ) <span className="req" aria-hidden="true">必須</span>
                  </label>
                  <input
                    id="cf-furigana"
                    type="text"
                    placeholder="例: ヤマダ タロウ"
                    value={f.furigana}
                    onChange={(e) => set("furigana", e.target.value)}
                    onBlur={() => touch("furigana")}
                    aria-required="true"
                    aria-invalid={!!visibleErrors.furigana}
                  />
                  {visibleErrors.furigana && <span className="field__err" role="alert">{visibleErrors.furigana}</span>}
                </div>
              </div>

              {/* メールアドレス */}
              <div className="field">
                <label htmlFor="cf-email">
                  メールアドレス <span className="req" aria-hidden="true">必須</span>
                </label>
                <input
                  id="cf-email"
                  type="email"
                  placeholder="example@email.com"
                  value={f.email}
                  onChange={(e) => set("email", e.target.value)}
                  onBlur={() => touch("email")}
                  aria-required="true"
                  aria-invalid={!!visibleErrors.email}
                />
                <span className="field__help">入力されたメールアドレスに返信いたします。</span>
                {visibleErrors.email && <span className="field__err" role="alert">{visibleErrors.email}</span>}
              </div>

              {/* お問い合わせ種別 */}
              <div className="field">
                <label htmlFor="cf-category">
                  お問い合わせ種別 <span className="req" aria-hidden="true">必須</span>
                </label>
                <select
                  id="cf-category"
                  value={f.category}
                  onChange={(e) => setCategory(e.target.value)}
                  onBlur={() => touch("category")}
                  aria-required="true"
                  aria-invalid={!!visibleErrors.category}
                >
                  <option value="" disabled>— 選択してください —</option>
                  {CONTACT_CATEGORIES.map((c) => <option key={c} value={c}>{c}</option>)}
                </select>
                {visibleErrors.category && <span className="field__err" role="alert">{visibleErrors.category}</span>}
              </div>

              {/* 領収書番号 */}
              {showReceiptNumber && (
                <div className="field">
                  <label htmlFor="cf-orderno">
                    領収書番号 <span className="req" aria-hidden="true">必須</span>
                  </label>
                  <input
                    id="cf-orderno"
                    type="text"
                    placeholder="領収書番号 XXXX-XXXX"
                    value={f.orderNo}
                    onChange={(e) => set("orderNo", e.target.value)}
                    onBlur={() => touch("orderNo")}
                    aria-required="true"
                    aria-invalid={!!visibleErrors.orderNo}
                  />
                  {visibleErrors.orderNo && <span className="field__err" role="alert">{visibleErrors.orderNo}</span>}
                </div>
              )}

              {/* 電話番号 */}
              {showPhoneNumber && (
                <div className="field">
                  <label htmlFor="cf-phone">
                    電話番号 <span className="req" aria-hidden="true">必須</span>
                  </label>
                  <input
                    id="cf-phone"
                    type="tel"
                    placeholder="例: 090-1234-5678"
                    value={f.phoneNumber}
                    onChange={(e) => set("phoneNumber", e.target.value)}
                    onBlur={() => touch("phoneNumber")}
                    aria-required="true"
                    aria-invalid={!!visibleErrors.phoneNumber}
                  />
                  {visibleErrors.phoneNumber && <span className="field__err" role="alert">{visibleErrors.phoneNumber}</span>}
                </div>
              )}

              {/* 初期不良確認 */}
              {showInitialDefectFields && (
                <>
                  <div className="field">
                    <label>
                      初期不良の確認 <span className="req" aria-hidden="true">必須</span>
                    </label>
                    <label className="checkbox">
                      <input
                        type="checkbox"
                        checked={f.defectAgreement}
                        onChange={(e) => set("defectAgreement", e.target.checked)}
                        onBlur={() => touch("defectAgreement")}
                        aria-required="true"
                      />
                      <span>
                        商品に破損・印刷不良など、使用に支障のある問題についての問い合わせです。
                        ハンドメイドおよび受注生産の性質を理解し、個体差や軽微な仕様差異に関する問い合わせではないことに同意します。
                      </span>
                    </label>
                    {visibleErrors.defectAgreement && <span className="field__err" role="alert">{visibleErrors.defectAgreement}</span>}
                  </div>

                  <div className="field">
                    <label htmlFor="cf-defect-images">
                      状態確認用の写真 <span className="req" aria-hidden="true">必須</span>
                    </label>
                    <input
                      id="cf-defect-images"
                      type="file"
                      accept="image/*"
                      multiple
                      onChange={(e) => setDefectImages(e.target.files)}
                      onBlur={() => touch("defectImages")}
                      aria-required="true"
                      aria-invalid={!!visibleErrors.defectImages}
                    />
                    <span className="field__help">
                      破損や印刷不良の状態が確認できる写真を添付してください。全体の様子と気になる箇所がわかる写真を、3枚まで選択できます。1枚あたり5MB以内の画像をご利用ください。
                    </span>
                    {f.defectImages.length > 0 && (
                      <span className="field__help">
                        添付済み: {f.defectImages.map((image) => image.name).join("、")}
                      </span>
                    )}
                    {visibleErrors.defectImages && <span className="field__err" role="alert">{visibleErrors.defectImages}</span>}
                  </div>
                </>
              )}

              {/* お問い合わせ内容 */}
              <div className="field">
                <label htmlFor="cf-message">
                  お問い合わせ内容 <span className="req" aria-hidden="true">必須</span>
                </label>
                <textarea
                  id="cf-message"
                  placeholder="ご質問・ご要望を詳しくお聞かせください。"
                  value={f.message}
                  onChange={(e) => set("message", e.target.value)}
                  onBlur={() => touch("message")}
                  aria-required="true"
                  aria-invalid={!!visibleErrors.message}
                />
                {visibleErrors.message && <span className="field__err" role="alert">{visibleErrors.message}</span>}
              </div>

              {/* プライバシーポリシー同意 */}
              <label className="checkbox">
                <input
                  type="checkbox"
                  checked={f.agreed}
                  onChange={(e) => set("agreed", e.target.checked)}
                  onBlur={() => touch("agreed")}
                  aria-required="true"
                />
                <span>
                  <a
                    onClick={() => go("privacy")}
                    style={{ color: "var(--c-accent)", fontWeight: 700, cursor: "pointer" }}
                  >プライバシーポリシー</a>
                  {" "}に同意のうえ送信します。
                </span>
              </label>
              {visibleErrors.agreed && <span className="field__err" role="alert">{visibleErrors.agreed}</span>}

              {/* Cloudflare Turnstile */}
              <div ref={turnstileRef} />

              {/* 送信エラー */}
              {submitError && (
                <div className="note" role="alert" style={{ marginBottom: 0 }}>
                  <div className="note__icon">!</div>
                  <div>{submitError}</div>
                </div>
              )}

              {/* 送信ボタン */}
              <button
                className="btn btn--accent btn--xl btn--block"
                type="submit"
                disabled={isSubmitting || !isFormValid}
                aria-busy={isSubmitting}
                style={(isSubmitting || !isFormValid) ? { opacity: 0.75, cursor: "not-allowed" } : {}}
              >
                {isSubmitting
                  ? <><span className="spinner" aria-hidden="true" /> 送信中...</>
                  : <><Icon name="mail" size={18} /> 送信する</>
                }
              </button>
            </form>
          )}
        </div>
      </div>
    </main>
  );
};

window.LCS = Object.assign(window.LCS, { ShopPage, AboutPage, FAQPage, ContactPage, TokushohoPage, PrivacyPage, TermsPage });
