// Yomee — App.jsx
// Router + App shell + ReactDOM mount. Loads last so all screens are declared.
/* global React, ReactDOM, IOSDevice, GlobalHelpHost, HelpSheetHost,
   StartScreen, SignUpScreen, SignInScreen,
   PersonalInfoScreen, IdentityValidationScreen, OnboardingWelcomeScreen,
   PushNotificationsScreen, NativePushDialog, Question1Screen, ProfileResultScreen,
   ProfileQuestionScreen, UploadScreen, AnalyzingScreen, ExtractionReviewScreen, RadiografiaScreen,
   QUESTIONS_BY_PROFILE,
   ProfileScreen,
   TweaksPanel, TweakSection, TweakRadio, TweakButton, useTweaks, FAKE_USER */

const { useState: useStateApp } = React;

// ────────────────────────────────────────────────
// In-app persona switcher (prototype only)
// 4 fixed personas — Ana / Luis / Carlos / Sofía — each maps to one of the
// classified profiles. The active persona is selected via the floating
// switcher pill (see PersonaSwitcher below). On switch, window.YomeeUser is
// rewritten and the Router is force-remounted so every screen re-reads the
// new values from screen 1.
// ────────────────────────────────────────────────
const YOMEE_PERSONAS = [
  {
    key: "ana",
    name: "Ana",
    email: "ana@email.com",
    age: "29",
    gender: "female",
    debt: 45000,
    payment: 45000,
    label: "Totalera",
    profile: "totalero",
    dot: "#1a6b3f",
  },
  {
    key: "luis",
    name: "Luis",
    email: "luis@email.com",
    age: "32",
    gender: "male",
    debt: 65000,
    payment: 12000,
    label: "Optimizador",
    profile: "optimizador",
    dot: "#185fa5",
  },
  {
    key: "carlos",
    name: "Carlos",
    email: "carlos@email.com",
    age: "36",
    gender: "male",
    debt: 80000,
    payment: 900,
    label: "Escalador",
    profile: "escalador",
    dot: "#7c2d12",
  },
  {
    key: "sofia",
    name: "Sofía",
    email: "sofia@email.com",
    age: "34",
    gender: "female",
    debt: 35000,
    payment: 0,
    label: "Reiniciadora",
    profile: "reiniciador",
    dot: "#4c1d95",
  },
];

function __yomeeBuildUser(persona) {
  return {
    name: persona.name,
    email: persona.email,
    age: persona.age,
    gender: persona.gender,
    debt: persona.debt,
    payment: persona.payment,
    profile: persona.profile,
    personaKey: persona.key,
  };
}

// Default active persona on load: Ana (Totalero).
const __YOMEE_INITIAL_PERSONA = YOMEE_PERSONAS[0];

// Helpers used across screens.
function __yomeeFirstName(full) {
  return (full || "").split(" ")[0] || "";
}
function __yomeeInitials(full) {
  const s = (full || "").trim();
  if (!s) return "";
  // First two letters of the first name, uppercased.
  return s.split(" ")[0].slice(0, 2).toUpperCase();
}

// Sync window.YomeeUser + the Google/Apple fake-account fixtures to the
// active persona. Called once at module init AND every time the user picks
// a different persona from the switcher.
function __yomeeApplyPersona(persona) {
  const u = __yomeeBuildUser(persona);
  window.YomeeUser = {
    ...u,
    firstName: __yomeeFirstName(u.name),
    initials: __yomeeInitials(u.name),
  };
  if (window.FAKE_USER) {
    ["google", "apple"].forEach((k) => {
      if (window.FAKE_USER[k]) {
        window.FAKE_USER[k].name = u.name;
        window.FAKE_USER[k].email = u.email;
        window.FAKE_USER[k].initial = (u.name[0] || "M").toUpperCase();
      }
    });
  }
}

__yomeeApplyPersona(__YOMEE_INITIAL_PERSONA);

// ────────────────────────────────────────────────
// Single global state source for the active persona. Every screen reads from
// this context — no screen keeps its own local copy of persona fields
// (name/email/age/gender/debt/payment) so a switch in the Demo pill
// propagates instantly to all mounted screens.
// ────────────────────────────────────────────────
const YomeeUserContext = React.createContext(window.YomeeUser);
window.YomeeUserContext = YomeeUserContext;
function useYomeeUser() {
  return React.useContext(YomeeUserContext);
}
window.useYomeeUser = useYomeeUser;

const ROUTES = [
  "start",
  "signup",
  "signin",
  "personal-info",
  "identity",
  "onb-welcome",
  "push",
  "question-1",
  "profile-result",
  "profile-questions",
  "upload",
  "analyzing",
  "review",
  "radiografia",
  "perfil",
];

function Router() {
  const [route, setRoute] = useStateApp("start");
  const [direction, setDirection] = useStateApp("forward");
  const [prev, setPrev] = useStateApp(null);
  const [authUser, setAuthUser] = useStateApp(null);
  // The active persona is the single source of truth for name/age/email/
  // gender/debt/payment. Pull it from context so a Demo-pill switch
  // updates every mounted screen instantly.
  const yomeeUser = useYomeeUser();
  // Local override for debt/monthly only when the user actually edits the
  // sliders during their session. null → show the active persona's values.
  const [debtOverride, setDebtOverride] = useStateApp(null);
  const debt =
    debtOverride != null
      ? debtOverride
      : { total: yomeeUser?.debt ?? 0, monthly: yomeeUser?.payment ?? 0 };
  const [pushDialog, setPushDialog] = useStateApp(false);
  // Profile-question state: which step of the per-profile question list,
  // and whether the user reached upload by skipping.
  const [pqStep, setPqStep] = useStateApp(0);
  const [pqSkipped, setPqSkipped] = useStateApp(false);
  const [pqProfile, setPqProfile] = useStateApp("optimizador");
  // Stored answer to the "¿Cuántas tarjetas de crédito tienes activas?" question.
  // null = not asked / skipped (treated as "1 tarjeta" downstream).
  // Possible values when set: "1 tarjeta" | "2 tarjetas" | "3 o más"
  const [cardsAnswer, setCardsAnswer] = useStateApp(null);
  // Uploaded files — lifted from UploadScreen so the Radiografía screen
  // can read the user's actual upload state (bank chips, progress bar,
  // counter), and so the user can return to Upload and add the missing
  // statements without losing what they already uploaded.
  // Each entry: { name, bank } where bank ∈ "bbva" | "nu" | "banorte".
  const [uploadedFiles, setUploadedFiles] = useStateApp([]);
  // Radiografía profile to render — driven by Tweaks. Defaults to Totalero.
  const [radioProfile, setRadioProfile] = useStateApp("totalero");
  const [radioScenario, setRadioScenario] = useStateApp("A");

  // Forced archetype on the profile-result screen — driven by Tweaks.
  // null = classify from debt/payment as usual.
  const [forcedArchetype, setForcedArchetype] = useStateApp(null);

  // Listen to Tweaks for profile + initial route.
  React.useEffect(() => {
    const onMsg = (e) => {
      if (!e?.data || typeof e.data !== "object") return;
      if (e.data.type === "yo-set-radio-profile") {
        setRadioProfile(e.data.profile);
      }
      if (e.data.type === "yo-set-radio-scenario") {
        setRadioScenario(e.data.scenario);
      }
      if (e.data.type === "yo-go-radiografia") {
        setRoute("radiografia");
      }
      if (e.data.type === "yo-go-start") {
        setRoute("start");
      }
      if (e.data.type === "yo-go-perfil") {
        setRoute("perfil");
      }
      if (e.data.type === "yo-go-review") {
        setRoute("review");
      }
      if (e.data.type === "yo-set-archetype") {
        setForcedArchetype(e.data.profile || null);
      }
      if (e.data.type === "yo-go-archetype") {
        if (e.data.profile) setForcedArchetype(e.data.profile);
        setRoute("profile-result");
      }
    };
    window.addEventListener("message", onMsg);
    return () => window.removeEventListener("message", onMsg);
  }, []);

  function navigate(next, dir = "forward") {
    if (next === route) return;
    setDirection(dir);
    setPrev(route);
    setRoute(next);
    setTimeout(() => setPrev(null), 320);
  }

  function handleAuthSuccess(provider, user) {
    setAuthUser({ provider, user });
    navigate("personal-info");
  }

  function renderScreen(name) {
    if (name === "start")
      return (
        <StartScreen
          onPrimary={() => navigate("signup")}
          onSignIn={() => navigate("signin")}
        />
      );
    if (name === "signup")
      return (
        <SignUpScreen
          onBack={() => navigate("start", "back")}
          onSwitchToSignIn={() => navigate("signin")}
          onDemo={() => alert("Ver radiografía demo")}
          onAuthSuccess={handleAuthSuccess}
        />
      );
    if (name === "signin")
      return (
        <SignInScreen
          onBack={() => navigate("start", "back")}
          onSwitchToSignUp={() => navigate("signup", "back")}
          onAuthSuccess={handleAuthSuccess}
        />
      );
    if (name === "personal-info")
      return (
        <PersonalInfoScreen
          onBack={() => navigate("start", "back")}
          onContinue={() => navigate("identity")}
        />
      );
    if (name === "identity")
      return (
        <IdentityValidationScreen
          email={yomeeUser?.email || "tu correo"}
          onBack={() => navigate("personal-info", "back")}
          onContinue={() => navigate("onb-welcome")}
        />
      );
    if (name === "onb-welcome")
      return (
        <OnboardingWelcomeScreen
          onContinue={() => navigate("push")}
        />
      );
    if (name === "push")
      return (
        <>
          <PushNotificationsScreen
            dimmed={pushDialog}
            onActivate={() => setPushDialog(true)}
            onSkip={() => navigate("question-1")}
          />
          {pushDialog && (
            <NativePushDialog
              onAllow={() => {
                setPushDialog(false);
                setTimeout(() => navigate("question-1"), 240);
              }}
              onDeny={() => {
                setPushDialog(false);
                setTimeout(() => navigate("question-1"), 240);
              }}
            />
          )}
        </>
      );
    if (name === "question-1")
      return (
        <Question1Screen
          onBack={() => navigate("push", "back")}
          onContinue={({ total, monthly }) => {
            setDebtOverride({ total, monthly });
            // Clear any Tweaks-forced archetype so the real
            // classification (debt / payment) wins on the result screen.
            // Without this, once a tester used the Tweaks "Ir a Archetype"
            // flow, forcedArchetype stuck around and pinned every
            // subsequent Question1 → profile-result transition to
            // "totalero" regardless of the numbers entered.
            setForcedArchetype(null);
            navigate("profile-result");
          }}
        />
      );
    if (name === "profile-result")
      return (
        <ProfileResultScreen
          deudaTotal={debt.total}
          pagoMensual={debt.monthly}
          gender={yomeeUser?.gender}
          forceProfile={forcedArchetype}
          onContinue={(p) => {
            setPqProfile(p);
            setPqStep(0);
            setPqSkipped(false);
            setCardsAnswer(null);
            // Totalero has no questions — go straight to upload.
            const list = (window.QUESTIONS_BY_PROFILE || {})[p] || [];
            if (list.length === 0) navigate("upload");
            else navigate("profile-questions");
          }}
        />
      );
    if (name === "profile-questions")
      return (
        <ProfileQuestionScreen
          key={`pq-${pqProfile}-${pqStep}`}
          profile={pqProfile}
          stepIndex={pqStep}
          onAnswer={(answer) => {
            const list =
              (window.QUESTIONS_BY_PROFILE || {})[pqProfile] || [];
            // If the just-answered question is a "cards count" question,
            // capture the answer. Two question variants exist across
            // archetypes (Optimizador/Escalador ask about active cards;
            // Reiniciador asks about cards with pending payments) — both
            // use the same option set and feed the same denominator on
            // the Radiografía progress card.
            const justAnswered = list[pqStep];
            const cardsQuestions = [
              "¿Cuántas tarjetas de crédito tienes activas?",
              "¿Cuántas tarjetas tienes con pagos pendientes?",
            ];
            if (justAnswered && cardsQuestions.includes(justAnswered.question)) {
              setCardsAnswer(answer);
            }
            if (pqStep + 1 >= list.length) {
              setPqSkipped(false);
              navigate("upload");
            } else {
              setPqStep(pqStep + 1);
              // stay on profile-questions; key change re-mounts
            }
          }}
          onSkip={() => {
            setPqSkipped(true);
            navigate("upload");
          }}
          onBack={() => {
            if (pqStep === 0) navigate("profile-result", "back");
            else setPqStep(pqStep - 1);
          }}
        />
      );
    if (name === "upload")
      return (
        <UploadScreen
          profile={pqProfile}
          skipped={pqSkipped}
          cardsAnswer={cardsAnswer}
          files={uploadedFiles}
          setFiles={setUploadedFiles}
          onContinue={(p) => {
            // Profile keys are already aligned with radiografía keys.
            setRadioProfile(p);
            // Always pass through the Analyzing transition before the
            // next destination is decided. The transition itself is
            // unconditional — the routing decision (Confidence Gate vs.
            // straight-to-Radiografía) happens when Analyzing finishes.
            navigate("analyzing");
          }}
          onDemo={() => alert("Ver radiografía demo")}
        />
      );
    if (name === "analyzing")
      return (
        <AnalyzingScreen
          fileCount={uploadedFiles.length}
          onDone={() => {
            // Confidence Gate: only when the user uploaded all 3 files do
            // we route through the extraction-review step. Anything less
            // skips it entirely (per spec).
            if (uploadedFiles.length === 3) {
              navigate("review");
            } else {
              navigate("radiografia");
            }
          }}
        />
      );
    if (name === "review")
      return (
        <ExtractionReviewScreen
          onBack={() => navigate("upload", "back")}
          onContinue={() => navigate("radiografia")}
        />
      );
    if (name === "radiografia")
      return (
        <RadiografiaScreen
          profile={radioProfile}
          scenario={radioScenario}
          cardsAnswer={cardsAnswer}
          uploadedFiles={uploadedFiles}
          setFiles={setUploadedFiles}
          onGoToUpload={() => navigate("upload", "back")}
          onOpenProfile={() => navigate("perfil")}
        />
      );
    if (name === "perfil")
      return (
        <ProfileScreen
          onBack={() => navigate("radiografia", "back")}
          onLoggedOut={() => navigate("start", "back")}
        />
      );
    return null;
  }

  const enterFrom = direction === "forward" ? "100%" : "-100%";
  const exitTo    = direction === "forward" ? "-100%" : "100%";

  return (
    <div style={{ position: "relative", width: "100%", height: "100%", overflow: "hidden" }}>
      {prev && (
        <div
          key={`prev-${prev}`}
          style={{
            position: "absolute",
            inset: 0,
            animation: `yo-slide-out 320ms ease-out forwards`,
            ["--exit-to"]: exitTo,
          }}
        >
          {renderScreen(prev)}
        </div>
      )}
      <div
        key={`cur-${route}`}
        style={{
          position: "absolute",
          inset: 0,
          animation: prev ? `yo-slide-in 320ms ease-out` : "none",
          ["--enter-from"]: enterFrom,
        }}
      >
        {renderScreen(route)}
      </div>
    </div>
  );
}

function YomeeTweaks() {
  const [profile, setProfile] = React.useState("totalero");
  const [scenario, setScenario] = React.useState("A");
  const [archetype, setArchetype] = React.useState("totalero");
  React.useEffect(() => {
    window.postMessage({ type: "yo-set-radio-profile", profile }, "*");
  }, [profile]);
  React.useEffect(() => {
    window.postMessage({ type: "yo-set-radio-scenario", scenario }, "*");
  }, [scenario]);
  React.useEffect(() => {
    window.postMessage({ type: "yo-set-archetype", profile: archetype }, "*");
  }, [archetype]);
  return (
    <TweaksPanel title="Tweaks">
      <TweakSection label="Navegación">
        <TweakButton
          label="Ir a Main Screen"
          onClick={() => window.postMessage({ type: "yo-go-start" }, "*")}
        />
        <TweakButton
          label="Ir a Mi perfil"
          onClick={() => window.postMessage({ type: "yo-go-perfil" }, "*")}
        />
        <TweakButton
          label="Ir a Confidence Gate"
          onClick={() => window.postMessage({ type: "yo-go-review" }, "*")}
        />
      </TweakSection>
      <TweakSection label="Archetype (perfil resultado)">
        {/* Order matters: pick the arquetipo FIRST, then tap the button.
            The button always navigates with the currently-selected
            arquetipo. Previously the button sat above the radio so users
            tapped it before changing the selection — and because a second
            (Radiografía) radio below has identical labels, clicks meant
            for this one were landing on the wrong control, leaving
            arquetipo at its default ("totalero") for every navigation. */}
        <TweakRadio
          label="Arquetipo (perfil resultado)"
          value={archetype}
          options={[
            { value: "totalero",    label: "Totalero"    },
            { value: "optimizador", label: "Optimizador" },
            { value: "escalador",   label: "Escalador"   },
            { value: "reiniciador", label: "Reiniciador" },
          ]}
          onChange={setArchetype}
        />
        <TweakButton
          label={`Ir a Archetype · ${archetype}`}
          onClick={() =>
            window.postMessage(
              { type: "yo-go-archetype", profile: archetype },
              "*",
            )
          }
        />
      </TweakSection>
      <TweakSection label="Radiografía">
        <TweakButton
          label="Ir a Radiografía"
          onClick={() => window.postMessage({ type: "yo-go-radiografia" }, "*")}
        />
        <TweakRadio
          label="Perfil"
          value={profile}
          options={[
            { value: "totalero",    label: "Totalero"    },
            { value: "optimizador", label: "Optimizador" },
            { value: "escalador",   label: "Escalador"   },
            { value: "reiniciador", label: "Reiniciador" },
          ]}
          onChange={setProfile}
        />
        <TweakRadio
          label="Escenario"
          value={scenario}
          options={[
            { value: "A", label: "A · 1/2"   },
            { value: "B", label: "B · 2/3"   },
            { value: "C", label: "C · stale" },
          ]}
          onChange={setScenario}
        />
      </TweakSection>
    </TweaksPanel>
  );
}

// ─────────────────────────────────────────────────────────────────────
// PersonaSwitcher — floating pill (bottom-right) that lets testers
// switch between the 4 personas without touching the URL. Tap the pill
// to open a card panel with one row per persona; tap a row to switch.
// Tapping outside or the pill again closes the panel.
// ─────────────────────────────────────────────────────────────────────
function PersonaSwitcher({ activeKey, onSelect }) {
  const [open, setOpen] = React.useState(false);
  const wrapRef = React.useRef(null);

  React.useEffect(() => {
    if (!open) return;
    const onDoc = (e) => {
      if (wrapRef.current && !wrapRef.current.contains(e.target)) {
        setOpen(false);
      }
    };
    document.addEventListener("mousedown", onDoc);
    document.addEventListener("touchstart", onDoc);
    return () => {
      document.removeEventListener("mousedown", onDoc);
      document.removeEventListener("touchstart", onDoc);
    };
  }, [open]);

  const active = YOMEE_PERSONAS.find((p) => p.key === activeKey) || YOMEE_PERSONAS[0];

  return (
    <div
      ref={wrapRef}
      style={{
        position: "fixed",
        right: 16,
        bottom: 16,
        zIndex: 2147483647,
        fontFamily:
          'ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif',
      }}
    >
      {open && (
        <div
          role="dialog"
          aria-label="Simular usuario"
          style={{
            position: "absolute",
            right: 0,
            bottom: 44,
            width: 220,
            background: "#fff",
            borderRadius: 16,
            boxShadow: "0 8px 32px rgba(0,0,0,0.18)",
            padding: "12px 12px 8px",
            boxSizing: "border-box",
          }}
        >
          <div
            style={{
              fontSize: 11,
              textTransform: "uppercase",
              color: "#999",
              letterSpacing: "0.08em",
              fontWeight: 600,
              marginBottom: 8,
              padding: "0 4px",
            }}
          >
            Simular usuario
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 2 }}>
            {YOMEE_PERSONAS.map((p) => {
              const isActive = p.key === activeKey;
              return (
                <button
                  key={p.key}
                  type="button"
                  onClick={() => {
                    onSelect(p.key);
                    setOpen(false);
                  }}
                  style={{
                    display: "flex",
                    alignItems: "center",
                    gap: 10,
                    width: "100%",
                    padding: "8px 10px",
                    border: 0,
                    background: isActive ? "#F5F5F5" : "transparent",
                    borderRadius: 10,
                    cursor: "pointer",
                    textAlign: "left",
                    color: "#1a1a1a",
                    fontFamily: "inherit",
                  }}
                >
                  <span
                    aria-hidden="true"
                    style={{
                      width: 10,
                      height: 10,
                      borderRadius: "50%",
                      background: p.dot,
                      flex: "0 0 auto",
                    }}
                  />
                  <span style={{ display: "flex", flexDirection: "column", flex: 1, minWidth: 0 }}>
                    <span style={{ fontSize: 13, fontWeight: 600, lineHeight: 1.2 }}>
                      {p.name}
                    </span>
                    <span style={{ fontSize: 11, color: "#999", lineHeight: 1.2 }}>
                      {p.label}
                    </span>
                  </span>
                  {isActive && (
                    <span
                      aria-label="Activo"
                      style={{ color: "#1a1a1a", fontSize: 14, fontWeight: 700 }}
                    >
                      ✓
                    </span>
                  )}
                </button>
              );
            })}
          </div>
        </div>
      )}

      <button
        type="button"
        aria-expanded={open}
        aria-label={`Simular usuario: ${active.name} (${active.label})`}
        onClick={() => setOpen((v) => !v)}
        style={{
          display: "inline-flex",
          alignItems: "center",
          gap: 6,
          background: "#1a1a1a",
          color: "#fff",
          fontSize: 12,
          fontWeight: 600,
          fontFamily: "inherit",
          border: 0,
          borderRadius: 20,
          padding: "8px 14px",
          cursor: "pointer",
          boxShadow: "0 4px 14px rgba(0,0,0,0.25)",
          lineHeight: 1,
        }}
      >
        <span aria-hidden="true">👤</span>
        <span>Demo</span>
      </button>
    </div>
  );
}

function App() {
  const [personaKey, setPersonaKey] = React.useState(__YOMEE_INITIAL_PERSONA.key);

  // Derive the active persona from personaKey. This is the single source of
  // truth shared with every screen via YomeeUserContext below.
  const activePersona = React.useMemo(() => {
    const p =
      YOMEE_PERSONAS.find((x) => x.key === personaKey) || YOMEE_PERSONAS[0];
    return {
      ...__yomeeBuildUser(p),
      firstName: __yomeeFirstName(p.name),
      initials: __yomeeInitials(p.name),
    };
  }, [personaKey]);

  // Mirror the active persona to window.YomeeUser + the SSO fixtures for any
  // legacy code paths that still read those globals. Runs synchronously
  // before children render so context + globals stay aligned.
  React.useLayoutEffect(() => {
    const persona =
      YOMEE_PERSONAS.find((p) => p.key === personaKey) || YOMEE_PERSONAS[0];
    __yomeeApplyPersona(persona);
  }, [personaKey]);

  return (
    <div
      style={{
        minHeight: "100vh",
        background: "#2a2d33",
        display: "flex",
        alignItems: "flex-start",
        justifyContent: "center",
        padding: "16px 12px",
        boxSizing: "border-box",
      }}
    >
      <YomeeTweaks />
      <style>{`
        @keyframes yo-slide-in {
          from { transform: translateX(var(--enter-from)); }
          to   { transform: translateX(0); }
        }
        @keyframes yo-slide-out {
          from { transform: translateX(0); }
          to   { transform: translateX(var(--exit-to)); }
        }
      `}</style>
      <IOSDevice statusBar={{ style: "dark", time: "9:41" }} dark={true}>
        <YomeeUserContext.Provider value={activePersona}>
          <Router />
          <GlobalHelpHost />
          <HelpSheetHost />
        </YomeeUserContext.Provider>
      </IOSDevice>

      <PersonaSwitcher activeKey={personaKey} onSelect={setPersonaKey} />
    </div>
  );
}

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