/* global React, ReactDOM, JOURNEYS, JOURNEY_ORDER, Phone, Backstage, Ic, progressPercent */
const { useState, useEffect, useCallback, useRef } = React;

const STANDARD_SUBS = [
  { key: "standard-low", label: "Low risk", sub: "Frictionless" },
  { key: "standard-medium", label: "Medium risk", sub: "+ Proof of address" },
  { key: "standard-pep", label: "PEP", sub: "+ EDD" },
];

function TopBar({ journeyKey, setJourney, present, togglePresent }) {
  const [openStd, setOpenStd] = useState(false);
  const isStd = journeyKey.startsWith("standard");
  const stdLabel = STANDARD_SUBS.find(s => s.key === journeyKey)?.label;
  const wrapRef = useRef(null);

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

  const tab = (k, label) => (
    <button key={k} className={"tab" + (journeyKey === k ? " active" : "")} onClick={() => setJourney(k)}>
      {label}
    </button>
  );
  return (
    <div className="topbar">
      <div className="brand">
        <svg width="32" height="32" viewBox="0 0 32 32" fill="none" style={{ color: "var(--teal)" }}>
          <circle cx="16" cy="16" r="13" stroke="currentColor" strokeWidth="2"/>
          <path d="M16 6 A10 10 0 0 1 26 16" stroke="currentColor" strokeWidth="2" strokeLinecap="round" fill="none"/>
        </svg>
        <div>
          <div className="name">Customer Onboarding</div>
          <div className="sub">Journeys · Prototype</div>
        </div>
      </div>
      <div className="tabs">
        {tab("entry", "Entry flow")}
        {tab("wallet", "Wallet")}
        {tab("basic", "Basic")}
        <div className="tab-wrap" ref={wrapRef}>
          <button className={"tab has-menu" + (isStd ? " active" : "")} onClick={() => setOpenStd(v => !v)}>
            Standard{isStd ? ` · ${stdLabel}` : ""} <span className="chev"><Ic.chev/></span>
          </button>
          {openStd && (
            <div className="submenu">
              {STANDARD_SUBS.map(s => (
                <button key={s.key} className={"item" + (journeyKey === s.key ? " active" : "")}
                  onClick={() => { setJourney(s.key); setOpenStd(false); }}>
                  <span>Standard — {s.label}</span><small>{s.sub}</small>
                </button>
              ))}
            </div>
          )}
        </div>
        {tab("sme", "Business Lite")}
        {tab("resume", "Resume")}
      </div>
      <button className={"present-btn" + (present ? " on" : "")} onClick={togglePresent} title="Toggle present mode">
        <Ic.eye/>
        <span>{present ? "Exit present" : "Present"}</span>
      </button>
    </div>
  );
}

const ENTRY_CTX_DEFAULT = { customerType: "individual", pillars: {}, businessEntityType: null, businessSignatories: null };

function App() {
  const [journeyKey, setJourneyKey] = useState(() => localStorage.getItem("onb.journey") || "entry");
  const [stepIdx, setStepIdx] = useState(() => parseInt(localStorage.getItem("onb.step") || "0", 10));
  const [opsState, setOpsState] = useState(() => localStorage.getItem("onb.ops") || "target");
  const [present, setPresent] = useState(() => localStorage.getItem("onb.present") === "1");
  const [entryCtx, setEntryCtx] = useState(() => {
    try {
      const raw = localStorage.getItem("onb.entryCtx");
      return raw ? { ...ENTRY_CTX_DEFAULT, ...JSON.parse(raw) } : { ...ENTRY_CTX_DEFAULT };
    } catch {
      return { ...ENTRY_CTX_DEFAULT };
    }
  });

  useEffect(() => { localStorage.setItem("onb.journey", journeyKey); }, [journeyKey]);
  useEffect(() => { localStorage.setItem("onb.step", String(stepIdx)); }, [stepIdx]);
  useEffect(() => { localStorage.setItem("onb.ops", opsState); }, [opsState]);
  useEffect(() => { localStorage.setItem("onb.present", present ? "1" : "0"); }, [present]);
  useEffect(() => {
    try { localStorage.setItem("onb.entryCtx", JSON.stringify(entryCtx)); } catch {}
  }, [entryCtx]);

  const journey = JOURNEYS[journeyKey];

  // Shape-only context used to evaluate step.when() predicates
  const whenCtx = {
    customerType: entryCtx.customerType,
    pillars: entryCtx.pillars,
    businessEntityType: entryCtx.businessEntityType,
    businessSignatories: entryCtx.businessSignatories,
    opsState,
  };
  const isStepVisible = (s) => !s.when || s.when(whenCtx);
  const visibleSteps = journey.steps.filter(isStepVisible);

  // If the persisted raw index points at a hidden step, shift to the next visible one
  const rawIdx = Math.min(stepIdx, journey.steps.length - 1);
  let resolvedIdx = rawIdx;
  while (resolvedIdx < journey.steps.length && !isStepVisible(journey.steps[resolvedIdx])) {
    resolvedIdx++;
  }
  if (resolvedIdx >= journey.steps.length) {
    resolvedIdx = journey.steps.length - 1;
    while (resolvedIdx > 0 && !isStepVisible(journey.steps[resolvedIdx])) resolvedIdx--;
  }
  const safeIdx = resolvedIdx;
  const step = journey.steps[safeIdx];
  const visibleIdx = visibleSteps.findIndex((s) => s.key === step.key);
  const visibleJourney = { ...journey, steps: visibleSteps };

  const setJourney = useCallback((k) => {
    setJourneyKey(k);
    setStepIdx(0);
  }, []);

  const next = useCallback(() => {
    setStepIdx((i) => {
      const steps = JOURNEYS[journeyKey].steps;
      let j = Math.min(i + 1, steps.length - 1);
      while (j < steps.length - 1 && steps[j].when && !steps[j].when(whenCtx)) j++;
      return j;
    });
  }, [journeyKey, whenCtx]);
  const prev = useCallback(() => {
    setStepIdx((i) => {
      const steps = JOURNEYS[journeyKey].steps;
      let j = Math.max(i - 1, 0);
      while (j > 0 && steps[j].when && !steps[j].when(whenCtx)) j--;
      return j;
    });
  }, [journeyKey, whenCtx]);

  // Keyboard nav
  useEffect(() => {
    const onKey = (e) => {
      if (e.target && ["INPUT","TEXTAREA"].includes(e.target.tagName)) return;
      if (e.key === "ArrowRight") next();
      else if (e.key === "ArrowLeft") prev();
      else if (e.key === "Escape" && present) setPresent(false);
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [next, prev, present]);

  // Build ctx passed into phone screens
  const ctx = {
    journey,
    stepIdx: safeIdx,
    progress: progressPercent(visibleJourney, Math.max(visibleIdx, 0)),
    next,
    prev,
    setCtx: (patch) => setEntryCtx(c => ({ ...c, ...patch })),
    customerType: entryCtx.customerType,
    pillars: entryCtx.pillars,
    businessEntityType: entryCtx.businessEntityType,
    businessSignatories: entryCtx.businessSignatories,
    cardChoice: entryCtx.cardChoice,
    pickupBranch: entryCtx.pickupBranch,
    opsState,
    jumpToJourney: (k) => { setJourneyKey(k); setStepIdx(0); },
  };

  return (
    <div className={"app" + (present ? " present" : "")}>
      <TopBar journeyKey={journeyKey} setJourney={setJourney} present={present} togglePresent={() => setPresent(v => !v)}/>

      <div className="body-split">
        <div className="stage">
          <div className="stage-inner">
            <div className="journey-label">
              <span className="dot"/>
              <span>{journey.name}</span>
              <span style={{ opacity: .5 }}>·</span>
              <span>Step {Math.max(visibleIdx, 0) + 1} of {visibleSteps.length}</span>
            </div>

            <Phone screenKey={step.screen} ctx={ctx} large={present}/>

            <div className="nav">
              <button className="arrow" onClick={prev} disabled={visibleIdx <= 0} aria-label="Previous"><Ic.arrowL/></button>
              <div className="dots">
                {visibleSteps.map((s) => {
                  const originalIdx = journey.steps.findIndex((x) => x.key === s.key);
                  return (
                    <button key={s.key} className={"dot-btn" + (s.key === step.key ? " active" : "")}
                      onClick={() => setStepIdx(originalIdx)} aria-label={s.label}>
                      <span className="tip">{s.label}</span>
                    </button>
                  );
                })}
              </div>
              <button className="arrow" onClick={next} disabled={visibleIdx >= visibleSteps.length - 1} aria-label="Next"><Ic.arrow/></button>
            </div>
            <div className="step-label">{step.label}</div>
          </div>
        </div>

        <Backstage step={step} opsState={opsState} setOpsState={setOpsState} collapsed={present}/>
      </div>
    </div>
  );
}

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