// app.jsx — アプリ本体（ヘッダー / ルーティング / フッター / Tweaks）
const { useState: useStateA, useEffect: useEffectA } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "wamodern",
  "accent": "#6d7a3c",
  "fontSize": 16,
  "radius": "default"
}/*EDITMODE-END*/;

const THEME_LABELS = { wamodern: "和モダン", natural: "ナチュラル", database: "データベース" };

function Header({ view, onNav, query, setQuery, onSearch }) {
  const [menu, setMenu] = useStateA(false);
  return (
    <header className="hdr">
      <div className="wrap hdr-row">
        <div className="brand" onClick={() => onNav("top")}>
          <div className="brand-mark"><Ico name="leaf" size={20} /></div>
          <div>
            <div className="brand-name">干し芋ナビ</div>
            <div className="brand-sub">HOSHIIMO NAVI</div>
          </div>
        </div>
        <form className="hdr-search" onSubmit={(e) => { e.preventDefault(); onSearch(); }}>
          <span className="ico"><Ico name="search" size={17} /></span>
          <input value={query} onChange={(e) => setQuery(e.target.value)}
            placeholder="商品名・メーカー・品種で検索" />
        </form>
        <nav className="hdr-nav">
          <a className={view === "top" ? "active" : ""} onClick={() => onNav("top")}>ホーム</a>
          <a className={view === "list" ? "active" : ""} onClick={() => onNav("list")}>商品一覧</a>
          <a onClick={() => { onNav("top"); setTimeout(() => document.getElementById("health")?.scrollIntoView?.({ behavior: "smooth" }), 50); }}>健康効果</a>
        </nav>
        <button className="hdr-burger" onClick={() => setMenu(true)} aria-label="メニュー"><Ico name="list" size={20} /></button>
      </div>
      {menu && (
        <div className="mob-menu">
          <button className="mm-close" onClick={() => setMenu(false)}><Ico name="close" /></button>
          <form className="hdr-search" style={{ display: "block", maxWidth: "none", marginBottom: 8 }}
            onSubmit={(e) => { e.preventDefault(); onSearch(); setMenu(false); }}>
            <span className="ico"><Ico name="search" size={17} /></span>
            <input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="検索" />
          </form>
          <a className={view === "top" ? "active" : ""} onClick={() => { onNav("top"); setMenu(false); }}>ホーム</a>
          <a className={view === "list" ? "active" : ""} onClick={() => { onNav("list"); setMenu(false); }}>商品一覧</a>
        </div>
      )}
    </header>
  );
}

function Footer({ onNav, onJump }) {
  const J = (id) => (e) => { e.preventDefault(); onJump(id); };
  const toList = (e) => { e.preventDefault(); onNav("list"); };
  return (
    <footer className="ftr">
      <div className="wrap ftr-grid">
        <div>
          <div className="brand" style={{ marginBottom: 12 }}>
            <div className="brand-mark"><Ico name="leaf" size={20} /></div>
            <div className="brand-name">干し芋ナビ</div>
          </div>
          <p style={{ fontSize: 13, color: "var(--ink-soft)", lineHeight: 1.7, margin: "0 0 12px", maxWidth: "26em" }}>
            国内の干し芋を品種・形状・メーカーで比較し、レビューとあわせて選べる情報サイトです。
          </p>
          <div className="aff-note">
            当サイトはアフィリエイトプログラムを利用しています。リンクから購入された場合、当サイトが報酬を得ることがあります。
          </div>
        </div>
        <div>
          <h6>さがす</h6>
          <a href="#" onClick={toList}>商品一覧</a><a href="#" onClick={toList}>人気ランキング</a><a href="#" onClick={J("variety")}>品種から探す</a><a href="#" onClick={toList}>メーカー一覧</a>
        </div>
        <div>
          <h6>知る</h6>
          <a href="#" onClick={J("health")}>干し芋の健康効果</a><a href="#" onClick={J("variety")}>品種ガイド</a><a href="#" onClick={J("howto")}>おいしい食べ方</a><a href="#" onClick={J("storage")}>保存方法</a>
        </div>
        <div>
          <h6>サイトについて</h6>
          <a href="#" onClick={J("about")}>運営者情報</a><a href="#" onClick={J("contact")}>お問い合わせ</a>
        </div>
      </div>
      <div className="wrap ftr-bottom">
        <span>© 2026 干し芋ナビ（サンプル）</span>
        <span>掲載の商品・価格はサンプルです。実際の情報に差し替えてご利用ください。</span>
      </div>
    </footer>
  );
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [view, setView] = useStateA("top");
  const [listFilters, setListFilters] = useStateA(null);
  const [modal, setModal] = useStateA(null);
  const [query, setQuery] = useStateA("");
  const [activeQuery, setActiveQuery] = useStateA("");
  const [, forceTick] = useStateA(0);

  // 管理画面でデータが変わったら公開サイトも更新（別タブ・同タブ両対応）
  useEffectA(() => {
    const refresh = () => { window.PRODUCTS = loadProducts(); forceTick((n) => n + 1); };
    window.addEventListener("storage", refresh);
    window.addEventListener("products-changed", refresh);
    window.addEventListener("masters-changed", refresh);
    return () => {
      window.removeEventListener("storage", refresh);
      window.removeEventListener("products-changed", refresh);
      window.removeEventListener("masters-changed", refresh);
    };
  }, []);

  // テーマ適用
  useEffectA(() => {
    document.documentElement.setAttribute("data-theme", t.theme);
    document.documentElement.style.setProperty("--base-fz", t.fontSize + "px");
    if (t.accent) {
      document.documentElement.style.setProperty("--olive", t.accent);
      // 濃色は accent をやや暗く
      document.documentElement.style.setProperty("--olive-deep",
        `color-mix(in srgb, ${t.accent} 78%, #1c2010)`);
    }
    if (t.radius === "sharp") {
      document.documentElement.style.setProperty("--radius", "4px");
      document.documentElement.style.setProperty("--radius-sm", "3px");
    } else if (t.radius === "round") {
      document.documentElement.style.setProperty("--radius", "24px");
      document.documentElement.style.setProperty("--radius-sm", "16px");
    } else {
      document.documentElement.style.removeProperty("--radius");
      document.documentElement.style.removeProperty("--radius-sm");
    }
  }, [t.theme, t.accent, t.fontSize, t.radius]);

  const goList = (presetFilters) => {
    setListFilters(presetFilters
      ? { variety: [], origin: [], shape: [], hardness: [], maker: [], tag: [], price: null, minRating: null, ...presetFilters }
      : null);
    setActiveQuery("");
    setView("list");
    window.scrollTo({ top: 0 });
  };
  const nav = (v) => { setView(v); if (v === "top") setActiveQuery(""); window.scrollTo({ top: 0 }); };
  const doSearch = () => { setActiveQuery(query); setListFilters(null); setView("list"); window.scrollTo({ top: 0 }); };
  const jumpTo = (id) => {
    setView("top"); setActiveQuery("");
    setTimeout(() => document.getElementById(id)?.scrollIntoView?.({ behavior: "smooth" }), 70);
  };

  return (
    <div className="app">
      <Header view={view} onNav={nav} query={query} setQuery={setQuery} onSearch={doSearch} />
      {view === "top"
        ? <TopPage onGoList={goList} onOpen={setModal} />
        : <ListPage key={JSON.stringify(listFilters) + activeQuery} initialFilters={listFilters} onOpen={setModal} query={activeQuery} />}
      <Footer onNav={nav} onJump={jumpTo} />
      {modal && <ProductModal p={modal} onClose={() => setModal(null)} />}

      <TweaksPanel>
        <TweakSection label="デザインテーマ" />
        <TweakRadio label="スタイル" value={t.theme}
          options={[
            { value: "wamodern", label: "和モダン" },
            { value: "natural", label: "ナチュラル" },
            { value: "database", label: "データ" },
          ]}
          onChange={(v) => setTweak("theme", v)} />
        <TweakSection label="配色・形状" />
        <TweakColor label="メインカラー" value={t.accent}
          options={["#6d7a3c", "#5e8a4e", "#4f7a3c", "#7a6a30", "#9a5a36"]}
          onChange={(v) => setTweak("accent", v)} />
        <TweakRadio label="角の丸み" value={t.radius}
          options={[
            { value: "sharp", label: "直線" },
            { value: "default", label: "標準" },
            { value: "round", label: "丸い" },
          ]}
          onChange={(v) => setTweak("radius", v)} />
        <TweakSection label="文字" />
        <TweakSlider label="文字サイズ" value={t.fontSize} min={14} max={19} step={1} unit="px"
          onChange={(v) => setTweak("fontSize", v)} />
      </TweaksPanel>
    </div>
  );
}

// マウント関数。CMSモード(__CMS_MODE)のときは、データ取得後に bootstrap から呼ぶ。
window.mountApp = function () {
  ReactDOM.createRoot(document.getElementById("root")).render(<App />);
};
if (!window.__CMS_MODE) {
  window.mountApp();
}
