/* Main App — view routing + tweaks + state */

function getStoredAuthUser() {
  try {
    return JSON.parse(window.localStorage.getItem("bannr_auth_user") || window.localStorage.getItem("bannr_google_auth") || "null");
  } catch (_) {
    return null;
  }
}

function App() {
  const allowedViews = window.__BANNR_DESIGN_PREVIEW__ ? ["top", "hearing", "result"] : ["top", "hearing", "result", "funnel"];
  const protectedViews = ["hearing", "result"];
  const initialHash = window.location.hash.replace("#", "");
  const initialAuthUser = getStoredAuthUser();
  const initialView = allowedViews.includes(initialHash) && (!protectedViews.includes(initialHash) || initialAuthUser) ? initialHash : "top";
  const [view, setView] = React.useState(initialView); // top | hearing | result | funnel
  const [form, setForm] = React.useState({
    platforms: [],
    ratio: "",
    name: "",
    desc: "",
    imageData: null,
    imageName: "",
    target: "",
  });
  const [aiSubmitState, setAiSubmitState] = React.useState({ status: "idle", error: "", response: null });
  const [generatedBanner, setGeneratedBanner] = React.useState(null);
  const [authUser, setAuthUser] = React.useState(initialAuthUser);
  const [authChecked, setAuthChecked] = React.useState(Boolean(initialAuthUser));
  const [authModalOpen, setAuthModalOpen] = React.useState(allowedViews.includes(initialHash) && protectedViews.includes(initialHash) && !initialAuthUser);
  const [tweaks, setTweak] = useTweaks(window.__TWEAKS__ || {
    accent: "indigo",
    topHero: "kinetic",
    bannerTemplate: "split",
  });

  /* Apply accent tweak globally */
  React.useEffect(() => {
    const root = document.documentElement;
    const accents = {
      indigo:  { a: "#818cf8", a2: "#a78bfa", a3: "#6366f1", soft: "rgba(129,140,248,0.14)", glow: "rgba(129,140,248,0.35)" },
      emerald: { a: "#34d399", a2: "#6ee7b7", a3: "#10b981", soft: "rgba(52,211,153,0.14)", glow: "rgba(52,211,153,0.35)" },
      rose:    { a: "#fb7185", a2: "#fda4af", a3: "#e11d48", soft: "rgba(251,113,133,0.14)", glow: "rgba(251,113,133,0.35)" },
      amber:   { a: "#fbbf24", a2: "#fcd34d", a3: "#d97706", soft: "rgba(251,191,36,0.14)", glow: "rgba(251,191,36,0.35)" },
    };
    const p = accents[tweaks.accent] || accents.indigo;
    root.style.setProperty("--accent", p.a);
    root.style.setProperty("--accent-2", p.a2);
    root.style.setProperty("--accent-3", p.a3);
    root.style.setProperty("--accent-soft", p.soft);
    root.style.setProperty("--accent-glow", p.glow);
    root.style.setProperty("--border-focus", p.a);
  }, [tweaks.accent]);

  const goto = (v) => {
    setView(v);
    window.history.replaceState(null, "", `#${v}`);
    window.scrollTo({ top: 0, behavior: "smooth" });
  };

  const requireAuth = () => {
    if (authUser) {
      goto("hearing");
      return;
    }
    setAuthModalOpen(true);
  };

  const handleNav = (v) => {
    if (protectedViews.includes(v) && !authUser) {
      setAuthModalOpen(true);
      return;
    }
    goto(v);
  };

  const handleSocialAuth = (provider) => {
    window.location.href = `/api/auth/${provider}/start`;
  };

  React.useEffect(() => {
    let cancelled = false;
    fetch("/api/auth/me", { credentials: "include", cache: "no-store" })
      .then((r) => r.ok ? r.json() : null)
      .then((data) => {
        if (cancelled) return;
        const user = data?.user || null;
        if (user) {
          window.localStorage.setItem("bannr_auth_user", JSON.stringify(user));
          window.localStorage.removeItem("bannr_google_auth");
          setAuthUser(user);
          setAuthModalOpen(false);
          const currentHash = window.location.hash.replace("#", "");
          if (protectedViews.includes(currentHash)) {
            setView(currentHash);
          }
        }
        setAuthChecked(true);
      })
      .catch(() => setAuthChecked(true));
    return () => { cancelled = true; };
  }, []);

  React.useEffect(() => {
    if (!authChecked) return;
    const currentHash = window.location.hash.replace("#", "");
    if (protectedViews.includes(currentHash) && !authUser) {
      window.history.replaceState(null, "", "#top");
      setAuthModalOpen(true);
    }
    if ((view === "hearing" || view === "result") && !authUser) {
      setView("top");
      window.history.replaceState(null, "", "#top");
      setAuthModalOpen(true);
    }
  }, [view, authUser, authChecked]);

  React.useEffect(() => {
    setAiSubmitState((s) => {
      if (s.status === "idle" || s.status === "sending") return s;
      setGeneratedBanner(null);
      return { status: "idle", error: "", response: null };
    });
  }, [form]);

  const handleBannerSubmit = async () => {
    if (window.__BANNR_DESIGN_PREVIEW__) {
      setAiSubmitState({
        status: "idle",
        error: "現在はデザイン確認用の公開版です。入力・生成機能は準備中です。",
        response: null,
      });
      return;
    }
    if (aiSubmitState.status === "sending" || aiSubmitState.status === "sent") return;
    setAiSubmitState({ status: "sending", error: "", response: null });
    try {
      const lang = document.documentElement.lang || "ja";
      const response = await window.submitBannerBriefToAI(form, lang);
      setAiSubmitState({ status: "sent", error: "", response });
      if (response?.image) {
        setGeneratedBanner(response);
        goto("result");
      }
    } catch (e) {
      console.error("[BANNR] AI submit failed:", e);
      setAiSubmitState({ status: "error", error: e.message || String(e), response: null });
    }
  };

  return (
    <I18nProvider>
      <div className="app-shell">
        <HeaderWithI18n onNav={handleNav} current={view} />
        {view === "top" && <TopPage onStart={requireAuth} />}
        {view === "hearing" && (
          <HearingPage
            form={form}
            setForm={setForm}
            onSubmit={handleBannerSubmit}
            submitState={aiSubmitState}
            onBack={() => goto("top")}
          />
        )}
        {view === "result" && (
          <ResultPage
            form={form}
            generatedBanner={generatedBanner}
            onBack={() => goto("hearing")}
            onOpenFunnel={() => goto("funnel")}
          />
        )}
        {view === "funnel" && (
          <FunnelLabPage
            form={form}
            onBack={() => goto("result")}
          />
        )}
        <GoogleAuthModal
          open={authModalOpen}
          onClose={() => setAuthModalOpen(false)}
          onSocialAuth={handleSocialAuth}
        />
        <Footer />
        <BannrTweaks tweaks={tweaks} setTweak={setTweak} />
      </div>
    </I18nProvider>
  );
}

/* Header needs to be inside I18nProvider; wrap it */
function HeaderWithI18n(props) {
  return <Header {...props} />;
}

function GoogleAuthModal({ open, onClose, onSocialAuth }) {
  if (!open) return null;

  return (
    <div className="auth-modal" role="dialog" aria-modal="true" aria-labelledby="social-auth-title">
      <div className="auth-modal__backdrop" onClick={onClose} />
      <div className="auth-modal__panel">
        <button className="auth-modal__close" type="button" onClick={onClose} aria-label="閉じる">×</button>
        <div className="auth-modal__badge">無料トライアル</div>
        <h2 id="social-auth-title">ログインして始める</h2>
        <p>
          無料で試すには、Google、Instagram、Xのいずれかで登録・ログインが必要です。
          ログイン後、そのままバナー作成フォームへ進めます。
        </p>
        <div className="social-auth-actions">
          <button className="social-auth-btn social-auth-btn--google" type="button" onClick={() => onSocialAuth("google")}>
            <span className="social-auth-btn__mark social-auth-btn__mark--google" aria-hidden="true">
              <svg viewBox="0 0 24 24" focusable="false">
                <path fill="#4285F4" d="M23.49 12.27c0-.83-.07-1.43-.23-2.05H12v3.95h6.62c-.13.98-.85 2.45-2.45 3.44l-.02.13 3.56 2.76.25.02c2.28-2.1 3.53-5.19 3.53-8.25Z" />
                <path fill="#34A853" d="M12 24c3.24 0 5.96-1.07 7.95-2.91l-3.78-2.93c-1.01.7-2.36 1.2-4.17 1.2-3.17 0-5.86-2.1-6.82-4.99l-.12.01-3.7 2.87-.05.13C3.29 21.3 7.35 24 12 24Z" />
                <path fill="#FBBC05" d="M5.18 14.37A7.4 7.4 0 0 1 4.79 12c0-.82.14-1.61.38-2.37l-.01-.14-3.75-2.91-.12.06A12 12 0 0 0 0 12c0 1.93.46 3.75 1.29 5.36l3.89-2.99Z" />
                <path fill="#EA4335" d="M12 4.64c2.25 0 3.77.97 4.64 1.78l3.39-3.31C17.95 1.17 15.24 0 12 0 7.35 0 3.29 2.7 1.31 6.64l3.87 3C6.15 6.75 8.83 4.64 12 4.64Z" />
              </svg>
            </span>
            Googleで続ける
          </button>
          <button className="social-auth-btn social-auth-btn--instagram" type="button" onClick={() => onSocialAuth("instagram")}>
            <span className="social-auth-btn__mark social-auth-btn__mark--instagram" aria-hidden="true">
              <svg viewBox="0 0 24 24" focusable="false">
                <rect x="5.2" y="5.2" width="13.6" height="13.6" rx="4.2" fill="none" stroke="currentColor" strokeWidth="2" />
                <circle cx="12" cy="12" r="3.3" fill="none" stroke="currentColor" strokeWidth="2" />
                <circle cx="16.6" cy="7.4" r="1.15" fill="currentColor" />
              </svg>
            </span>
            Instagramで続ける
          </button>
          <button className="social-auth-btn social-auth-btn--x" type="button" onClick={() => onSocialAuth("x")}>
            <span className="social-auth-btn__mark social-auth-btn__mark--x" aria-hidden="true">𝕏</span>
            Xで続ける
          </button>
        </div>
        <p className="auth-modal__note">
          メールアドレスのみでの登録はできません。認証は各サービス上で行われます。
        </p>
      </div>
    </div>
  );
}

/* Tweaks panel content */
function BannrTweaks({ tweaks, setTweak }) {
  return (
    <TweaksPanel title="Tweaks">
      <TweakSection label="Brand">
        <TweakColor
          label="Accent color"
          value={tweaks.accent}
          options={["indigo", "emerald", "rose", "amber"]}
          colorMap={{
            indigo: "#818cf8",
            emerald: "#34d399",
            rose: "#fb7185",
            amber: "#fbbf24",
          }}
          onChange={(v) => setTweak("accent", v)}
        />
      </TweakSection>
      <TweakSection label="Result page">
        <TweakRadio
          label="Default template"
          value={tweaks.bannerTemplate}
          options={[
            { value: "split", label: "Split" },
            { value: "overlay", label: "Overlay" },
            { value: "minimal", label: "Minimal" },
          ]}
          onChange={(v) => setTweak("bannerTemplate", v)}
        />
      </TweakSection>
    </TweaksPanel>
  );
}

/* Custom TweakColor wrapper using the swatch approach the docs mention,
   but rendered as named-option swatches keyed off our colorMap */
function TweakColor({ label, value, options, colorMap, onChange }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
      <div style={{ fontSize: 12, color: "var(--text-2)", fontWeight: 500 }}>{label}</div>
      <div style={{ display: "flex", gap: 8 }}>
        {options.map((opt) => (
          <button
            key={opt}
            onClick={() => onChange(opt)}
            title={opt}
            style={{
              width: 32, height: 32, borderRadius: 8, cursor: "pointer",
              background: colorMap[opt],
              border: value === opt ? "2px solid #fff" : "2px solid transparent",
              outline: value === opt ? "1px solid rgba(255,255,255,0.4)" : "1px solid var(--border)",
              outlineOffset: 0,
              padding: 0,
            }}
          />
        ))}
      </div>
    </div>
  );
}

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