/* global React, ReactDOM, IOSDevice */
/* global TweaksPanel, useTweaks, TweakSection, TweakRadio, TweakToggle, TweakColor */
/* global LvTabBar, MessagingInbox, Conversation, Roster, RosterDetail, Settings */
/* global ProfileEdit, InviteTeammate, PaymentMethod */
/* global PhoneEntry, CodeVerify */
/* global LVRD_THREADS, LVRD_AGENT */

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "light",
  "density": "cozy",
  "accent": "space"
}/*EDITMODE-END*/;

// When this page is embedded in the marketing site, the parent
// drives the theme via a URL search param and via postMessage
// (so flipping the toggle on the site swaps the phone too).
// In embed mode we also strip the centered-phone chrome (body
// padding + tinted background) so the device fills the iframe.
(function applyEmbedTheme() {
  try {
    const u = new URL(window.location.href);
    const t = u.searchParams.get("theme");
    if (t === "dark" || t === "light") {
      TWEAK_DEFAULTS.theme = t;
      if (document.documentElement) document.documentElement.classList.add("embedded");
      if (document.body) document.body.classList.add("embedded");
    }
  } catch (e) { /* no-op */ }
})();

const ACCENTS = {
  // Each accent is the canonical Deep Spectrum hue at slightly
  // different lightness anchors. Stays inside the brand system.
  windsor:   { accent: "#0D1126", accentHover: "#1A224C", accentPress: "#0A0E1E" },
  space:     { accent: "#1A224C", accentHover: "#263373", accentPress: "#0D1126" },
  astronaut: { accent: "#263373", accentHover: "#31439B", accentPress: "#1A224C" },
  marian:    { accent: "#31439B", accentHover: "#3E54B8", accentPress: "#263373" },
};

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [tab, setTab] = React.useState("messaging");
  // messaging stack: null = inbox, otherwise thread id
  const [openThread, setOpenThread] = React.useState("t-quote");
  // roster stack: null = list, otherwise agent id
  const [openAgent, setOpenAgent] = React.useState(null);
  // settings stack: null = list, or "profile" / "invite" / "payment"
  const [settingsView, setSettingsView] = React.useState(null);
  // send mode: text | voice (for the bottom composer)
  const [sendMode, setSendMode] = React.useState("text");

  // Auth state: "phone" | "code" | "authed"
  // Check localStorage on mount; embedded demo iframe skips auth.
  const [authState, setAuthState] = React.useState(function () {
    const isEmbed = typeof document !== "undefined" &&
      document.body && document.body.classList.contains("embedded");
    if (isEmbed) return "authed";
    try {
      return localStorage.getItem("lvrd_session_token") ? "authed" : "phone";
    } catch (e) {
      return "phone";
    }
  });
  const [authPhone, setAuthPhone] = React.useState("");

  async function handleLogout() {
    const token = (function () {
      try { return localStorage.getItem("lvrd_session_token"); } catch (e) { return null; }
    })();
    if (token) {
      try {
        await fetch("https://app.lvrd.ai/api/auth/logout", {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + token,
          },
        });
      } catch (e) { /* always clear locally regardless */ }
    }
    try { localStorage.removeItem("lvrd_session_token"); } catch (e) {}
    setAuthState("phone");
    setAuthPhone("");
    setTab("messaging");
    setOpenThread("t-quote");
    setOpenAgent(null);
    setSettingsView(null);
  }

  const dark = t.theme === "dark";

  // Apply theme + accent override to the phone shell (and body)
  React.useEffect(() => {
    document.documentElement.setAttribute("data-theme", t.theme);
    document.body.setAttribute("data-app-theme", t.theme);
  }, [t.theme]);

  // Listen for theme changes posted from the embedding page (the
  // marketing site swaps light/dark when a user flips the toggle
  // in the Operator preview section).
  React.useEffect(() => {
    const handler = (e) => {
      const d = e && e.data;
      if (!d || d.type !== "lvrd-set-theme") return;
      if (d.theme === "dark" || d.theme === "light") {
        setTweak("theme", d.theme);
      }
    };
    window.addEventListener("message", handler);
    return () => window.removeEventListener("message", handler);
  }, [setTweak]);

  // Inline accent override — wraps the phone in a style scope.
  const accentVars = ACCENTS[t.accent] || ACCENTS.space;
  const accentStyle = dark ? {} : {
    "--accent": accentVars.accent,
    "--accent-hover": accentVars.accentHover,
    "--accent-press": accentVars.accentPress,
    "--accent-ring": "color-mix(in oklab, " + accentVars.accent + " 35%, transparent)",
  };

  function switchTab(t) {
    setTab(t);
    // when leaving settings, drop any open sub-view
    if (t !== "settings") setSettingsView(null);
    if (t !== "roster") setOpenAgent(null);
  }

  // Inbox stack: navigation in/out of a thread
  function openThreadId(id) { setOpenThread(id); }
  function backToInbox() { setOpenThread(null); }

  const thread = openThread ? LVRD_THREADS.find((x) => x.id === openThread) : null;
  const agent = openAgent ? window.LVRD_AGENTS.find((a) => a.id === openAgent) : null;

  let screen;
  if (tab === "messaging") {
    if (thread) {
      screen = (
        <Conversation
          thread={thread}
          onBack={backToInbox}
          sendMode={sendMode}
          setSendMode={setSendMode}
          onViewAgent={(agentId) => {
            setOpenThread(null);
            setOpenAgent(agentId);
            setTab("roster");
          }}
          onHandoff={() => {
            // jump to the Chief of Staff thread
            setOpenThread("t-chief");
          }}
          data-screen-label={"02 Conversation \u00b7 " + LVRD_AGENT(thread.agentId).name}
        />
      );
    } else {
      screen = (
        <MessagingInbox
          onOpenThread={openThreadId}
          sendMode={sendMode}
          setSendMode={setSendMode}
        />
      );
    }
  } else if (tab === "roster") {
    if (agent) {
      screen = (
        <RosterDetail
          agent={agent}
          onBack={() => setOpenAgent(null)}
          onSendDirective={() => {
            setOpenAgent(null);
            setTab("messaging");
          }}
        />
      );
    } else {
      screen = <Roster onOpenAgent={(id) => setOpenAgent(id)} />;
    }
  } else if (tab === "settings") {
    if (settingsView === "profile") {
      screen = <ProfileEdit onBack={() => setSettingsView(null)} onSave={() => setSettingsView(null)} />;
    } else if (settingsView === "invite") {
      screen = <InviteTeammate onBack={() => setSettingsView(null)} onSend={() => setSettingsView(null)} />;
    } else if (settingsView === "payment") {
      screen = <PaymentMethod onBack={() => setSettingsView(null)} onSave={() => setSettingsView(null)} />;
    } else {
      screen = <Settings theme={t.theme} setTheme={(v) => setTweak("theme", v)} openSub={setSettingsView} onLogout={handleLogout} />;
    }
  }

  // Phone screen labels for [data-screen-label]
  let label = "01 Messaging \u00b7 Inbox";
  if (authState === "phone") label = "00 Sign in";
  if (authState === "code")  label = "00 Verify code";
  if (tab === "messaging" && thread) label = "02 Conversation \u00b7 " + LVRD_AGENT(thread.agentId).name;
  if (tab === "roster" && !agent) label = "03 Roster";
  if (tab === "roster" && agent) label = "04 Roster \u00b7 " + agent.name;
  if (tab === "settings") label = "05 Account";
  if (tab === "settings" && settingsView === "profile") label = "06 Account \u00b7 Profile";
  if (tab === "settings" && settingsView === "invite") label = "07 Account \u00b7 Invite";
  if (tab === "settings" && settingsView === "payment") label = "08 Account \u00b7 Payment";

  // Badge appears on the messaging tab when there's a waiting approval
  const hasWaiting = LVRD_THREADS.some(t => t.section === "waiting");

  // Choose screen content: auth screens gate the main app
  let phoneContent;
  if (authState === "phone") {
    phoneContent = (
      <div className="lv-screen">
        <PhoneEntry
          onSent={function (e164) { setAuthPhone(e164); setAuthState("code"); }}
        />
      </div>
    );
  } else if (authState === "code") {
    phoneContent = (
      <div className="lv-screen">
        <CodeVerify
          phone={authPhone}
          onBack={function () { setAuthState("phone"); }}
          onVerified={function () { setAuthState("authed"); }}
        />
      </div>
    );
  } else {
    phoneContent = (
      <React.Fragment>
        <div className="lv-screen">{screen}</div>
        <LvTabBar tab={tab} onTab={switchTab} badge={hasWaiting ? "messaging" : null} />
      </React.Fragment>
    );
  }

  return (
    <React.Fragment>
      <IOSDevice dark={dark} width={402} height={874}>
        <div className="lv-phone" style={accentStyle} data-screen-label={label}>
          {phoneContent}
        </div>
      </IOSDevice>

      <TweaksPanel title="Tweaks">
        <TweakSection label="Appearance">
          <TweakRadio
            label="Theme"
            value={t.theme}
            onChange={(v) => setTweak("theme", v)}
            options={[
              { label: "Light", value: "light" },
              { label: "Dark", value: "dark" },
            ]}
          />
          <TweakRadio
            label="Accent"
            value={t.accent}
            onChange={(v) => setTweak("accent", v)}
            options={[
              { label: "Quiet", value: "windsor" },
              { label: "Default", value: "space" },
              { label: "Brand", value: "marian" },
            ]}
          />
        </TweakSection>
        <TweakSection label="Scenario">
          <div style={{ fontSize: 11, color: "rgba(41,38,27,.7)", lineHeight: 1.5 }}>
            {"Mid-day Tuesday \u00b7 1:24 PM. One approval waiting from The Quote Writer. Two completions landed today. Four quiet threads."}
          </div>
        </TweakSection>
      </TweaksPanel>
    </React.Fragment>
  );
}

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