// Interactive prototype shell for VaultOS Mobile.
// Wraps existing static screens in a state machine + click overlays so user can
// tap through ALL 5 flows: drop-in/BLE, onboarding, PIN, daily use, lock-up.
//
// Convention: each flow is a list of { id, render(ctx) } steps. ctx exposes
// `next`, `goto`, `tap` and shared state.

const { useState, useEffect, useRef, useCallback } = React;

const STORAGE_KEY = "vaultos.proto.v1";
const Mi3 = () => window.MIcons;
const D3 = () => window.M_DATA;
const S1 = () => window.MScreens;
const S2 = () => window.MScreens2;

// JSX-safe wrappers (capitalized) — defer lookup until render
const Home      = (p) => { const C = window.MScreens.Screen_Home;  return <C {...p}/>; };
const Unit      = (p) => { const C = window.MScreens.Screen_Unit;  return <C {...p}/>; };
const Unlock    = (p) => { const C = window.MScreens2.Screen_Unlock; return <C {...p}/>; };
const Wayfind   = (p) => { const C = window.MScreens2.Screen_Wayfind; return <C {...p}/>; };
const Access    = (p) => { const C = window.MScreens2.Screen_Access; return <C {...p}/>; };
const Billing   = (p) => { const C = window.MScreens2.Screen_Billing; return <C {...p}/>; };
const Account   = (p) => { const C = window.MScreens2.Screen_Account; return <C {...p}/>; };
const OnbWelcome  = (p) => { const C = window.MScreens2.Screen_Onboard_Welcome; return <C {...p}/>; };
const OnbPickSize = (p) => { const C = window.MScreens2.Screen_Onboard_PickSize; return <C {...p}/>; };
const OnbConfirm  = (p) => { const C = window.MScreens2.Screen_Onboard_Confirm; return <C {...p}/>; };
const LockReminder = (p) => { const C = window.MScreens2.Screen_LockReminder; return <C {...p}/>; };

// ─────────────────────────────────────────────────────────────
// Tap shim — wraps a screen, overlays an invisible button at given coords
// ─────────────────────────────────────────────────────────────
const TapTarget = ({ top, left, right, bottom, width, height, onClick, label, debug }) => (
  <button
    onClick={onClick}
    aria-label={label}
    style={{
      position: "absolute", top, left, right, bottom, width, height,
      background: debug ? "rgba(255,0,0,0.18)" : "transparent",
      border: "none", cursor: "pointer", padding: 0, margin: 0, zIndex: 50,
    }}
  />
);

// Floating "next" hint when there's no obvious tap target
const NextHint = ({ onClick, label = "Continue" }) => (
  <div style={{
    position: "absolute", left: 16, right: 16, bottom: 100, zIndex: 60,
  }}>
    <button onClick={onClick} className="m-btn primary lg full" style={{ boxShadow: "0 12px 32px -8px rgba(79,70,229,0.7), 0 0 0 1px rgba(124,108,255,0.4)" }}>
      {label}
    </button>
  </div>
);

// Banner along top of phone for narrative context
const FlowChrome = ({ flow, step, total, onExit, label }) => (
  <div style={{
    position: "absolute", top: 6, left: 14, right: 14, zIndex: 70,
    display: "flex", alignItems: "center", gap: 8, pointerEvents: "none",
  }}>
    <button
      onClick={onExit}
      style={{
        pointerEvents: "auto",
        height: 22, padding: "0 8px",
        background: "rgba(20,24,36,0.7)", backdropFilter: "blur(20px)",
        border: "1px solid rgba(255,255,255,0.1)", borderRadius: 99,
        color: "rgba(255,255,255,0.85)", fontSize: 10.5, fontWeight: 500,
        cursor: "pointer", display: "inline-flex", alignItems: "center", gap: 4,
      }}>
      ✕ Exit
    </button>
    <div style={{
      flex: 1, height: 22,
      display: "flex", alignItems: "center", justifyContent: "center", gap: 4,
    }}>
      {Array.from({ length: total }).map((_, i) => (
        <div key={i} style={{
          height: 3, flex: 1, maxWidth: 24, borderRadius: 99,
          background: i <= step ? "rgba(124,108,255,0.85)" : "rgba(255,255,255,0.12)",
          transition: "200ms",
        }}/>
      ))}
    </div>
    <div style={{
      pointerEvents: "auto",
      height: 22, padding: "0 8px",
      background: "rgba(20,24,36,0.7)", backdropFilter: "blur(20px)",
      border: "1px solid rgba(255,255,255,0.1)", borderRadius: 99,
      color: "rgba(255,255,255,0.85)", fontSize: 10.5, fontWeight: 500,
      display: "inline-flex", alignItems: "center",
    }}>
      {step + 1}/{total}
    </div>
  </div>
);

// Tiny toast (e.g. "Lock opened")
const Toast = ({ icon, title, body, tone = "ok" }) => {
  const Mi = Mi3();
  const Icon = icon ? Mi[icon] : Mi.check;
  const c = tone === "ok" ? "#6ee7b7" : tone === "warn" ? "#fcd34d" : "#7c6cff";
  return (
    <div className="m-toast" style={{ animation: "m-toast-in 240ms ease-out" }}>
      <div style={{
        width: 32, height: 32, borderRadius: 10,
        background: `color-mix(in oklab, ${c} 22%, transparent)`,
        display: "grid", placeItems: "center", flexShrink: 0,
      }}>
        <Icon size={18} color={c} strokeWidth={2}/>
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 13.5, fontWeight: 500, color: "white" }}>{title}</div>
        {body && <div style={{ fontSize: 12, color: "var(--m-tx-2)", marginTop: 1 }}>{body}</div>}
      </div>
    </div>
  );
};

// Big tappable phone face — passes through clicks unless explicit overlay
const ClickableFace = ({ onTap, hint, children }) => (
  <div onClick={onTap} style={{ position: "relative", width: "100%", height: "100%", cursor: hint ? "pointer" : "default" }}>
    {children}
    {hint && (
      <div style={{
        position: "absolute", bottom: 38, left: "50%", transform: "translateX(-50%)",
        background: "rgba(20,24,36,0.85)", backdropFilter: "blur(20px)",
        border: "1px solid rgba(255,255,255,0.12)", borderRadius: 99,
        padding: "6px 12px", fontSize: 11.5, color: "rgba(255,255,255,0.85)",
        zIndex: 65, pointerEvents: "none",
        animation: "m-toast-in 300ms ease-out",
      }}>
        {hint}
      </div>
    )}
  </div>
);

// ─────────────────────────────────────────────────────────────
// Flow definitions
// ─────────────────────────────────────────────────────────────

const FLOWS = {
  dropin: {
    label: "Self drop-in",
    sub: "Walk up · find unit · unlock with phone",
    icon: "ble",
    accent: "#7c6cff",
    steps: [
      // 0 — Home tile
      ({ next }) => (
        <ClickableFace hint="Tap anywhere to start at the gate">
          <Home/>
          <TapTarget top={0} left={0} right={0} bottom={0} onClick={next}/>
        </ClickableFace>
      ),
      // 1 — Wayfinding
      ({ next }) => (
        <>
          <Wayfind/>
          <NextHint onClick={next} label="I'm at the gate · Unlock"/>
        </>
      ),
      // 2 — BLE scanning
      ({ next }) => (
        <>
          <Unlock stage="scanning"/>
          <NextHint onClick={next} label="Phone detected the lock"/>
        </>
      ),
      // 3 — Hold near lock
      ({ next }) => (
        <>
          <Unlock stage="hold"/>
          <NextHint onClick={next} label="Hold complete · Authorize"/>
        </>
      ),
      // 4 — Unlocked
      ({ next, toast }) => {
        useEffect(() => { toast({ title: "Lock opened", body: "B-115 · You have 2 min to enter" }); }, []);
        return (
          <>
            <Unlock stage="success"/>
            <NextHint onClick={next} label="Done"/>
          </>
        );
      },
      // 5 — Back at home
      ({ exit }) => (
        <ClickableFace hint="Drop-in complete">
          <Home/>
          <TapTarget top={0} left={0} right={0} bottom={0} onClick={exit}/>
        </ClickableFace>
      ),
    ],
  },

  onboarding: {
    label: "Sign up & first unlock",
    sub: "Pick a unit · sign · move in",
    icon: "package",
    accent: "#22d3ee",
    steps: [
      ({ next }) => (
        <ClickableFace hint="Tap to begin">
          <OnbWelcome/>
          <TapTarget top={0} left={0} right={0} bottom={0} onClick={next}/>
        </ClickableFace>
      ),
      ({ next }) => (
        <>
          <OnbPickSize/>
          <TapTarget bottom={20} left={108} right={18} height={56} onClick={next} label="Continue"/>
        </>
      ),
      ({ next }) => (
        <>
          <OnbConfirm/>
          <TapTarget bottom={20} left={18} right={18} height={64} onClick={next} label="Sign and pay"/>
        </>
      ),
      // First unlock right after signup
      ({ next, toast }) => {
        useEffect(() => { toast({ title: "Welcome!", body: "Your unit is ready", tone: "ok" }); }, []);
        return (
          <ClickableFace hint="You're in. Try unlocking your new unit.">
            <Home/>
            <TapTarget top={0} left={0} right={0} bottom={0} onClick={next}/>
          </ClickableFace>
        );
      },
      ({ exit }) => (
        <ClickableFace hint="Onboarding complete">
          <Unlock stage="success"/>
          <TapTarget top={0} left={0} right={0} bottom={0} onClick={exit}/>
        </ClickableFace>
      ),
    ],
  },

  pin: {
    label: "PIN gate (offline)",
    sub: "Type your PIN at the gate",
    icon: "qr",
    accent: "#fbbf24",
    steps: [
      // Provide PIN-typing experience by re-mounting Screen_Access with growing entered
      ({ next, state, set }) => {
        const entered = state.pin || "";
        const onKey = (k) => {
          if (k === "back") set({ pin: entered.slice(0, -1) });
          else if (entered.length < 4) {
            const np = entered + k;
            set({ pin: np });
            if (np.length === 4) setTimeout(next, 400);
          }
        };
        return <PinScreen entered={entered} onKey={onKey}/>;
      },
      ({ next, toast }) => {
        useEffect(() => { toast({ title: "PIN accepted", body: "Gate 2 opened" }); }, []);
        return (
          <>
            <Unlock stage="success"/>
            <NextHint onClick={next} label="Continue to my unit"/>
          </>
        );
      },
      ({ exit }) => (
        <ClickableFace hint="PIN flow complete">
          <Home/>
          <TapTarget top={0} left={0} right={0} bottom={0} onClick={exit}/>
        </ClickableFace>
      ),
    ],
  },

  daily: {
    label: "Daily use",
    sub: "Home · Unit · Billing tabs",
    icon: "home",
    accent: "#10b981",
    steps: [
      ({ tab, setTab }) => <TabbedShell tab={tab || "home"} setTab={setTab}/>,
    ],
    customNav: true, // hide step pips, use tab bar
  },

  reminder: {
    label: "Lock-up reminder",
    sub: "Push notification → tap to lock",
    icon: "bell",
    accent: "#ef4444",
    steps: [
      ({ next, toast }) => {
        useEffect(() => {
          const t = setTimeout(() => toast({ title: "VaultOS · Reminder", body: "Did you lock up B-115? It's been 32 min.", tone: "warn", icon: "bell" }), 600);
          return () => clearTimeout(t);
        }, []);
        return (
          <ClickableFace hint="Tap the notification to open">
            <Home/>
            <TapTarget bottom={110} left={16} right={16} height={68} onClick={next} label="Open notification"/>
          </ClickableFace>
        );
      },
      ({ next }) => (
        <>
          <LockReminder/>
          <TapTarget bottom={20} left={146} right={18} height={52} onClick={next} label="Lock now"/>
        </>
      ),
      ({ exit, toast }) => {
        useEffect(() => { toast({ title: "Locked", body: "B-115 · Confirmed by lock sensor" }); }, []);
        return (
          <ClickableFace hint="All secure">
            <Home/>
            <TapTarget top={0} left={0} right={0} bottom={0} onClick={exit}/>
          </ClickableFace>
        );
      },
    ],
  },
};

// ─────────────────────────────────────────────────────────────
// PIN screen with live keypad
// ─────────────────────────────────────────────────────────────
const PinScreen = ({ entered, onKey }) => {
  const Mi = Mi3(); const d = D3();
  const filled = entered.length;
  return (
    <div className="m-page">
      <div className="m-header">
        <button className="m-iconbtn"><Mi.back size={18}/></button>
        <h1>Access</h1>
        <button className="m-iconbtn"><Mi.history size={18}/></button>
      </div>
      <div className="m-scroll">
        <div style={{ display: "flex", background: "var(--m-ink-2)", borderRadius: 14, padding: 4, gap: 4, border: "1px solid var(--m-line)" }}>
          {["PIN", "QR code", "Digital key"].map((m, i) => (
            <button key={m} style={{
              flex: 1, height: 36, borderRadius: 10, border: "none",
              background: i === 0 ? "var(--m-accent)" : "transparent",
              color: i === 0 ? "white" : "var(--m-tx-2)",
              fontSize: 13, fontWeight: 500, cursor: "pointer", fontFamily: "inherit",
            }}>{m}</button>
          ))}
        </div>

        <div style={{ textAlign: "center", margin: "32px 0 8px" }}>
          <div style={{ fontSize: 13, color: "var(--m-tx-2)", marginBottom: 6 }}>
            Enter your 4-digit PIN at any gate
          </div>
          <div style={{ fontSize: 12, color: "var(--m-tx-3)" }}>
            Gate 2 · {d.facility.name.split("·")[1].trim()}
          </div>
        </div>

        <div style={{ marginTop: 24, marginBottom: 28 }}>
          <div className="m-pin-dots">
            {[0,1,2,3].map(i => <div key={i} className={"m-pin-dot " + (i < filled ? "on" : "")} />)}
          </div>
        </div>

        <div className="m-keypad">
          {[1,2,3,4,5,6,7,8,9].map(n =>
            <button key={n} onClick={() => onKey(String(n))}>{n}</button>
          )}
          <button className="flat"><Mi.qr size={20} color="var(--m-tx-2)"/></button>
          <button onClick={() => onKey("0")}>0</button>
          <button className="flat" onClick={() => onKey("back")}><Mi.back size={20} color="var(--m-tx-2)"/></button>
        </div>

        <div style={{ marginTop: 24, padding: "12px 14px", background: "var(--m-ink-2)", borderRadius: 14, display: "flex", alignItems: "center", gap: 10, border: "1px solid var(--m-line)" }}>
          <Mi.shield size={18} color="var(--m-cyan)"/>
          <div style={{ flex: 1, fontSize: 12.5, color: "var(--m-tx-2)" }}>
            PIN access works even when your phone is offline.
          </div>
        </div>
      </div>
    </div>
  );
};

// ─────────────────────────────────────────────────────────────
// Tabbed shell for "Daily use" — swap screens with bottom tabs
// ─────────────────────────────────────────────────────────────
const TabbedShell = ({ tab, setTab }) => {
  const Mi = Mi3();
  const screens = {
    home: <Home/>,
    unit: <Unit/>,
    access: <Access/>,
    billing: <Billing/>,
    account: <Account/>,
  };
  // Render the chosen screen, then OVERLAY a real interactive tab bar on top
  // (the screen's own tabbar is non-interactive, but we cover it with our own).
  const tabs = [
    { id: "home", label: "Home",  ic: "home"  },
    { id: "unit", label: "My Unit", ic: "unit" },
    { id: "access", label: "Access", ic: "qr" },
    { id: "billing", label: "Billing", ic: "card" },
    { id: "account", label: "Account", ic: "user" },
  ];
  return (
    <div className="m-proto-tabbar-host" style={{ position: "relative", width: "100%", height: "100%" }}>
      {screens[tab]}
      <div className="m-tabbar" style={{ zIndex: 80 }}>
        <div className="tabs">
          {tabs.map((t) => {
            const Icon = Mi[t.ic];
            return (
              <button key={t.id} className="m-tab"
                data-active={tab === t.id}
                onClick={() => setTab(t.id)}>
                <Icon size={18} strokeWidth={1.8}/>
                <span>{t.label}</span>
              </button>
            );
          })}
        </div>
      </div>
    </div>
  );
};

// ─────────────────────────────────────────────────────────────
// Flow picker (initial home / between flows)
// ─────────────────────────────────────────────────────────────
const FlowPicker = ({ onPick }) => {
  const Mi = Mi3(); const d = D3();
  return (
    <div className="m-page" style={{ paddingTop: 62, position: "relative", overflow: "hidden" }}>
      <div style={{
        position: "absolute", top: 40, right: -60, width: 240, height: 240, borderRadius: "50%",
        background: "radial-gradient(closest-side, rgba(124,108,255,0.4), transparent 70%)",
        filter: "blur(20px)", pointerEvents: "none",
      }}/>
      <div style={{ padding: "8px 22px 14px" }}>
        <div style={{ fontSize: 13, color: "var(--m-tx-2)", fontWeight: 500 }}>Interactive demo</div>
        <div style={{ fontSize: 26, fontWeight: 600, letterSpacing: "-0.02em", marginTop: 2 }}>Pick a flow</div>
        <div style={{ fontSize: 13.5, color: "var(--m-tx-2)", marginTop: 6, lineHeight: 1.5 }}>
          Tap a card to walk through that journey end-to-end. Buttons inside are wired.
        </div>
      </div>

      <div className="m-scroll">
        <div className="m-stack">
          {Object.entries(FLOWS).map(([id, f]) => {
            const Icon = Mi[f.icon];
            return (
              <button key={id} onClick={() => onPick(id)} style={{
                background: "var(--m-ink-2)", border: "1px solid var(--m-line)",
                borderRadius: 18, padding: 14, display: "flex", alignItems: "center", gap: 14,
                cursor: "pointer", fontFamily: "inherit", color: "inherit", textAlign: "left",
                transition: "transform 120ms, border-color 120ms",
              }}
              onMouseDown={e => e.currentTarget.style.transform = "scale(0.98)"}
              onMouseUp={e => e.currentTarget.style.transform = ""}
              onMouseLeave={e => e.currentTarget.style.transform = ""}>
                <div style={{
                  width: 52, height: 52, borderRadius: 14,
                  background: `linear-gradient(140deg, ${f.accent}, ${shade(f.accent, -30)})`,
                  display: "grid", placeItems: "center",
                  boxShadow: `inset 0 1px 0 rgba(255,255,255,0.18), 0 8px 16px -8px ${f.accent}`,
                }}>
                  <Icon size={24} color="white" strokeWidth={1.8}/>
                </div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
                    <div style={{ fontSize: 15, fontWeight: 600 }}>{f.label}</div>
                    <span style={{ fontSize: 10.5, color: "var(--m-tx-3)", fontFamily: "Geist Mono" }}>
                      {f.steps.length} {f.steps.length === 1 ? "screen" : "steps"}
                    </span>
                  </div>
                  <div style={{ fontSize: 12.5, color: "var(--m-tx-2)", marginTop: 2 }}>{f.sub}</div>
                </div>
                <Mi.arrow size={18} color="var(--m-tx-3)"/>
              </button>
            );
          })}
        </div>

        <div style={{ marginTop: 24, padding: 14, background: "var(--m-ink-2)", borderRadius: 16, border: "1px solid var(--m-line)" }}>
          <div style={{ display: "flex", gap: 10, alignItems: "flex-start" }}>
            <div style={{ width: 32, height: 32, borderRadius: 9, background: "var(--m-accent-soft)", display: "grid", placeItems: "center", flexShrink: 0 }}>
              <Mi.alert size={16} color="var(--m-accent-2)"/>
            </div>
            <div style={{ fontSize: 12.5, color: "var(--m-tx-2)", lineHeight: 1.5 }}>
              <strong style={{ color: "var(--m-tx-1)" }}>Tip.</strong> Look for the bottom call-to-action button or tap anywhere on the screen to advance. Use ✕ Exit at the top to return here.
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

// ─────────────────────────────────────────────────────────────
// Helpers
// ─────────────────────────────────────────────────────────────
function shade(hex, percent) {
  // simple hex shade; percent positive lightens, negative darkens
  let h = hex.replace("#", "");
  if (h.length === 3) h = h.split("").map(x => x + x).join("");
  const num = parseInt(h, 16);
  let r = (num >> 16) + percent;
  let g = ((num >> 8) & 0xff) + percent;
  let b = (num & 0xff) + percent;
  r = Math.max(0, Math.min(255, r));
  g = Math.max(0, Math.min(255, g));
  b = Math.max(0, Math.min(255, b));
  return "#" + ((r << 16) | (g << 8) | b).toString(16).padStart(6, "0");
}

// ─────────────────────────────────────────────────────────────
// Main controller
// ─────────────────────────────────────────────────────────────
const Prototype = () => {
  const [persisted, setPersisted] = useState(() => {
    try { return JSON.parse(localStorage.getItem(STORAGE_KEY)) || {}; } catch { return {}; }
  });
  const [flowId, setFlowId] = useState(persisted.flowId || null);
  const [step, setStep] = useState(persisted.step || 0);
  const [shared, setShared] = useState(persisted.shared || {});
  const [toast, setToast] = useState(null);
  const [pulsing, setPulsing] = useState(false);
  const toastTimer = useRef(null);

  // Persist
  useEffect(() => {
    localStorage.setItem(STORAGE_KEY, JSON.stringify({ flowId, step, shared }));
  }, [flowId, step, shared]);

  const showToast = useCallback((opts) => {
    setToast(opts);
    clearTimeout(toastTimer.current);
    toastTimer.current = setTimeout(() => setToast(null), 2800);
  }, []);

  const flow = flowId ? FLOWS[flowId] : null;

  const next = useCallback(() => {
    if (!flow) return;
    setPulsing(true);
    setTimeout(() => setPulsing(false), 220);
    if (step + 1 >= flow.steps.length) {
      // finish: back to picker
      setFlowId(null); setStep(0); setShared({});
    } else {
      setStep(s => s + 1);
    }
  }, [flow, step]);

  const exit = useCallback(() => {
    setFlowId(null); setStep(0); setShared({}); setToast(null);
  }, []);

  const setSharedKey = useCallback((patch) => {
    setShared(s => ({ ...s, ...patch }));
  }, []);

  const ctx = {
    next, exit, toast: showToast,
    state: shared, set: setSharedKey,
    tab: shared.tab, setTab: (t) => setSharedKey({ tab: t }),
  };

  const StepEl = flow ? flow.steps[Math.min(step, flow.steps.length - 1)] : null;

  return (
    <div style={{
      minHeight: "100vh",
      background: "radial-gradient(60% 60% at 30% 20%, #1a1530 0%, #0a0c12 60%)",
      display: "flex", flexDirection: "column", alignItems: "center",
      padding: "20px 0 40px",
      gap: 12,
    }}>
      {flow && (
        <div style={{ width: 402, display: "flex", justifyContent: "flex-end" }}>
          <button onClick={exit} style={{
            height: 30, padding: "0 12px", borderRadius: 8,
            background: "rgba(255,255,255,0.06)", border: "1px solid rgba(255,255,255,0.1)",
            color: "rgba(255,255,255,0.85)", fontSize: 12, cursor: "pointer", fontFamily: "inherit",
          }}>Back to flows</button>
        </div>
      )}

      {/* Phone */}
      <div style={{
        position: "relative",
        transform: pulsing ? "scale(0.997)" : "scale(1)",
        transition: "transform 200ms",
      }}>
        <window.IOSDevice width={402} height={874} dark={true}>
          <div style={{ position: "relative", width: "100%", height: "100%" }}>
            {flow ? <StepEl {...ctx}/> : <FlowPicker onPick={(id) => { setFlowId(id); setStep(0); setShared({}); }}/>}
            {toast && <Toast {...toast}/>}
          </div>
        </window.IOSDevice>
      </div>

      <style>{`
        @keyframes m-toast-in {
          from { opacity: 0; transform: translateY(8px); }
          to { opacity: 1; transform: translateY(0); }
        }
      `}</style>
    </div>
  );
};

window.MProto = { Prototype };
