// 株価急騰要因メモ — app shell
// Wires iOS frame + tweaks + page navigation

const { useState, useEffect } = React;

// 公開ビルド判定：公開版HTMLで window.PUBLIC_BUILD = true をセット。
// true のとき iPhoneベゼル・Tweaksパネルを外し、実端末フルスクリーンで表示する。
const PUBLIC_BUILD = !!window.PUBLIC_BUILD;

// 画面幅で PC / スマホを判定。PC(>=1000px)では全幅レイアウト、
// それ未満では従来の iPhone フレーム表示にする。
function useIsDesktop(bp = 1000) {
  const q = `(min-width: ${bp}px)`;
  const [is, setIs] = useState(() => typeof window !== "undefined" && window.matchMedia(q).matches);
  useEffect(() => {
    const m = window.matchMedia(q);
    const h = (e) => setIs(e.matches);
    m.addEventListener ? m.addEventListener("change", h) : m.addListener(h);
    setIs(m.matches);
    return () => { m.removeEventListener ? m.removeEventListener("change", h) : m.removeListener(h); };
  }, [q]);
  return is;
}

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "showLiveTicker": true,
  "accent": "navy",
  "marketPalette": "jp"
}/*EDITMODE-END*/;

// タブのルートページ — これらに遷移したら履歴をリセットする
const TAB_ROOTS = ["home", "cats", "archive", "watch", "report", "plan"];

// URLハッシュで直接開けるページ（例: /#legal → 特商法表記）。Stripe審査等でURL提出に使う。
const HASH_PAGES = ["home", "cats", "archive", "watch", "report", "plan", "legal", "scouter"];

function App() {
  // ページ遷移履歴のスタック。最後の要素が現在のページ。
  const [history, setHistory] = useState(() => {
    const h = (window.location.hash || "").replace(/^#\/?/, "");
    return [{ page: HASH_PAGES.includes(h) ? h : "home", data: null }];
  });
  const current = history[history.length - 1];
  const page = current.page;
  const pageData = current.data;
  const scrollRef = React.useRef(null);
  const [t, setTweak] = window.useTweaks(TWEAK_DEFAULTS);
  const live = window.useLiveData ? window.useLiveData() : { status: "fallback" };

  // Apply tweak: accent color
  useEffect(() => {
    const root = document.documentElement;
    if (t.accent === "ink") {
      root.style.setProperty("--navy", "#0B1220");
      root.style.setProperty("--navy-deep", "#000000");
    } else if (t.accent === "indigo") {
      root.style.setProperty("--navy", "#2A3B6E");
      root.style.setProperty("--navy-deep", "#1A2548");
    } else {
      root.style.setProperty("--navy", "#14223D");
      root.style.setProperty("--navy-deep", "#0A1226");
    }
    // Market color convention
    if (t.marketPalette === "us") {
      root.style.setProperty("--up", "#1F7A3A");
      root.style.setProperty("--up-soft", "#E9F3EC");
      root.style.setProperty("--down", "#C8333A");
      root.style.setProperty("--down-soft", "#FBECEC");
    } else {
      root.style.setProperty("--up", "#C8333A");
      root.style.setProperty("--up-soft", "#FBECEC");
      root.style.setProperty("--down", "#1F7A3A");
      root.style.setProperty("--down-soft", "#E9F3EC");
    }
  }, [t.accent, t.marketPalette]);

  const _scrollTop = () => {
    setTimeout(() => {
      if (scrollRef.current) scrollRef.current.scrollTop = 0;
    }, 10);
  };

  const navigate = (p, data) => {
    setHistory(h => {
      // タブのルートへ移動するときは履歴を畳んで1件に
      if (TAB_ROOTS.includes(p)) return [{ page: p, data: data || null }];
      // 同じページの重複pushは避ける
      const top = h[h.length - 1];
      if (top && top.page === p && top.data === (data || null)) return h;
      return [...h, { page: p, data: data || null }];
    });
    // 直リンク可能なページはURLハッシュを同期（履歴は汚さない）
    try {
      window.history.replaceState(null, "", HASH_PAGES.includes(p) && p !== "home" ? "#" + p : window.location.pathname + window.location.search);
    } catch (e) {}
    _scrollTop();
  };

  // 一つ前のページへ戻る。履歴がなければホームへ。
  const goBack = () => {
    setHistory(h => (h.length > 1 ? h.slice(0, -1) : [{ page: "home", data: null }]));
    _scrollTop();
  };

  const tabKey = ["home"].includes(page) ? "home"
    : ["cats", "category"].includes(page) ? "cats"
    : ["archive"].includes(page) ? "archive"
    : ["watch"].includes(page) ? "watch"
    : ["report"].includes(page) ? "report"
    : ["plan"].includes(page) ? "plan"
    : null;

  let body = null;
  switch (page) {
    case "home":     body = <HomePage navigate={navigate}/>; break;
    case "surges":   body = <SurgesPage navigate={navigate}/>; break;
    case "stock":    body = <StockDetailPage stock={pageData} navigate={navigate} goBack={goBack}/>; break;
    case "cats":     body = <CategoriesPage navigate={navigate}/>; break;
    case "category": body = <CategoryPage cat={pageData} navigate={navigate} goBack={goBack}/>; break;
    case "theme":    body = <ThemePage theme={pageData} navigate={navigate} goBack={goBack}/>; break;
    case "archive":  body = <ArchivePage navigate={navigate}/>; break;
    case "watch":    body = <WatchlistPage navigate={navigate}/>; break;
    case "report":   body = <ReportPage navigate={navigate}/>; break;
    case "plan":     body = <PlanPage navigate={navigate} goBack={goBack}/>; break;
    case "article":  body = <ArticlePage article={pageData} navigate={navigate} goBack={goBack}/>; break;
    case "legal":    body = <LegalPage navigate={navigate} goBack={goBack}/>; break;
    case "scouter":  body = window.ScouterPage ? <window.ScouterPage navigate={navigate} goBack={goBack}/> : <HomePage navigate={navigate}/>; break;
    default:         body = <HomePage navigate={navigate}/>;
  }

  const isReportPage = page === "report";
  const isDesktop = useIsDesktop();

  // ===== PC（全幅）レイアウト：左サイドバー + 中央コンテンツ列 =====
  if (isDesktop) {
    const navItems = [
      { k: "home",    label: "ホーム",     Icon: window.IconHome },
      { k: "cats",    label: "カテゴリ",   Icon: window.IconGrid },
      { k: "archive", label: "アーカイブ", Icon: window.IconArchive },
      { k: "watch",   label: "ウォッチ",   Icon: window.IconStar },
      { k: "report",  label: "レポート",   Icon: window.IconChart },
      { k: "plan",    label: "プラン",     Icon: window.IconCrown },
    ];
    return (
      <>
        <div className="dk-root">
          <aside className="dk-sidebar">
            <div className="dk-brand">
              <button
                className="tappable"
                onClick={() => navigate("home")}
                aria-label="ホームへ戻る"
                style={{ background: "transparent", border: "none", padding: 0, cursor: "pointer", textAlign: "left", display: "block" }}
              >
                <span className="mincho dk-logo">初動さん</span>
                <span className="dk-sub" style={{ display: "block" }}>株価急騰要因メモ</span>
              </button>
              <div style={{ marginTop: 12 }}>
                {window.ConnectionPill && <window.ConnectionPill status={live.status}/>}
              </div>
            </div>
            <nav className="dk-nav">
              {navItems.map(({ k, label, Icon }) => {
                const a = tabKey === k;
                return (
                  <button key={k} className={"dk-navbtn tappable" + (a ? " active" : "")} onClick={() => navigate(k)}>
                    <span className="dk-navmark"/>
                    {Icon ? <Icon active={a}/> : null}
                    <span>{label}</span>
                  </button>
                );
              })}
            </nav>
            <div className="dk-foot">
              本サイトの情報は特定銘柄の売買を推奨するものではありません。投資判断はご自身の責任で行ってください。
              <a
                href="#"
                onClick={e => { e.preventDefault(); navigate("legal"); }}
                style={{ display: "block", marginTop: 8, color: "rgba(231,226,212,0.55)", textDecoration: "underline", textUnderlineOffset: 2 }}
              >特定商取引法に基づく表記</a>
            </div>
          </aside>
          <main className="dk-main">
            {t.showLiveTicker && <Ticker stocks={live.stocks && live.stocks.length ? live.stocks : SURGE_STOCKS}/>}
            <div ref={scrollRef} className="dk-content">
              <div className="dk-col app" key={page} style={{ height: "auto", paddingTop: 0, paddingBottom: 40, overflow: "visible", display: "block" }}>
                {body}
              </div>
            </div>
          </main>
        </div>

        {/* Tweaks panel */}
        {renderTweaks(t, setTweak)}
      </>
    );
  }

  return (
    <>
      <div className="app" style={PUBLIC_BUILD ? {
        height: "100dvh",
        paddingTop: "calc(env(safe-area-inset-top, 0px) + 10px)",
        paddingBottom: "calc(env(safe-area-inset-bottom, 0px) + 4px)",
      } : undefined}>
        {!isReportPage && <TopBar onMenu={() => navigate("plan")} onHome={() => navigate("home")} status={live.status}/>}
        {!isReportPage && t.showLiveTicker && <Ticker stocks={live.stocks && live.stocks.length ? live.stocks : SURGE_STOCKS}/>}
        <div ref={scrollRef} className="scroll" key={page}>
          {body}
        </div>
        {tabKey !== null && <TabBar active={tabKey} onChange={(k) => {
          if (k === "home") navigate("home");
          else if (k === "cats") navigate("cats");
          else if (k === "archive") navigate("archive");
          else if (k === "watch") navigate("watch");
          else if (k === "report") navigate("report");
          else if (k === "plan") navigate("plan");
        }}/>}
      </div>

      {/* Tweaks panel */}
      {renderTweaks(t, setTweak)}
    </>
  );
}

// Tweaks panel（PC/スマホ両レイアウトで共有）
function renderTweaks(t, setTweak) {
  if (PUBLIC_BUILD) return null;
  return (
      <window.TweaksPanel title="Tweaks">
        <window.TweakSection label="表示">
          <window.TweakToggle
            label="ライブティッカー"
            value={t.showLiveTicker}
            onChange={v => setTweak("showLiveTicker", v)}
          />
        </window.TweakSection>
        <window.TweakSection label="アクセント">
          <window.TweakRadio
            label="メイン"
            value={t.accent}
            options={[
              { label: "ネイビー", value: "navy" },
              { label: "インディゴ", value: "indigo" },
              { label: "ブラック", value: "ink" },
            ]}
            onChange={v => setTweak("accent", v)}
          />
        </window.TweakSection>
        <window.TweakSection label="色彩規則">
          <window.TweakRadio
            label="上昇=色"
            value={t.marketPalette}
            options={[
              { label: "赤=上昇(JP)", value: "jp" },
              { label: "緑=上昇(US)", value: "us" },
            ]}
            onChange={v => setTweak("marketPalette", v)}
          />
        </window.TweakSection>
      </window.TweaksPanel>
  );
}

// Render: PC は全幅、スマホは iPhone フレーム中央表示
function Root() {
  const isDesktop = useIsDesktop();
  const content = (
    <window.LiveDataProvider>
      <App/>
    </window.LiveDataProvider>
  );
  if (isDesktop || PUBLIC_BUILD) return content;
  return (
    <div style={{
      minHeight: "100vh", width: "100%",
      display: "flex", alignItems: "center", justifyContent: "center",
      padding: "32px 16px",
      background: "#1c1c1a",
      backgroundImage: "radial-gradient(circle at 30% 20%, #2b2a26 0%, #1c1c1a 60%)",
    }}>
      <IOSDevice width={402} height={874} dark={true}>
        {content}
      </IOSDevice>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<Root/>);
