/* global React */
const { useState, useEffect, useRef, useMemo, useCallback, createContext, useContext } = React;

// ====================== SVG ICONS (line, monochrome) ======================
const I = {
  back: (p = {}) => (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M15 18l-6-6 6-6" /></svg>
  ),
  forward: (p = {}) => (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M9 18l6-6-6-6" /></svg>
  ),
  search: (p = {}) => (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="11" cy="11" r="7"/><path d="M21 21l-3.6-3.6"/></svg>
  ),
  bell: (p = {}) => (
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M6 8a6 6 0 0112 0c0 7 3 7 3 9H3c0-2 3-2 3-9z"/><path d="M9 21a3 3 0 006 0"/></svg>
  ),
  bluetooth: (p = {}) => (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M7 7l10 10-5 5V2l5 5L7 17"/></svg>
  ),
  mail: (p = {}) => (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3 7l9 6 9-6"/></svg>
  ),
  lock: (p = {}) => (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V7a4 4 0 018 0v4"/></svg>
  ),
  user: (p = {}) => (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="12" cy="8" r="4"/><path d="M4 21c1.5-4 4.5-6 8-6s6.5 2 8 6"/></svg>
  ),
  eye: (p = {}) => (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12z"/><circle cx="12" cy="12" r="3"/></svg>
  ),
  phone: (p = {}) => (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="6" y="2" width="12" height="20" rx="3"/><path d="M11 18h2"/></svg>
  ),
  heart: (p = {}) => (
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 21s-7-4.5-9.5-9A5 5 0 0112 6a5 5 0 019.5 6c-2.5 4.5-9.5 9-9.5 9z"/></svg>
  ),
  drop: (p = {}) => (
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 3s6 7 6 11a6 6 0 11-12 0c0-4 6-11 6-11z"/></svg>
  ),
  lung: (p = {}) => (
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 4v10M5 8c-1 4-1 8 0 11 2 2 5 0 5-3v-7C8 7 6 7 5 8zM19 8c1 4 1 8 0 11-2 2-5 0-5-3v-7c2-2 4-2 5-1z"/></svg>
  ),
  temp: (p = {}) => (
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M10 14V5a2 2 0 014 0v9a4 4 0 11-4 0z"/><circle cx="12" cy="17" r="1.5" fill="currentColor"/></svg>
  ),
  bp: (p = {}) => (
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M3 12h4l2-5 4 10 2-5h6"/></svg>
  ),
  building: (p = {}) => (
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M4 21V8l8-4 8 4v13"/><path d="M9 21v-5h6v5M9 11h2M13 11h2M9 14h2M13 14h2"/></svg>
  ),
  device: (p = {}) => (
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="3" y="4" width="18" height="13" rx="2"/><path d="M8 21h8M12 17v4M7 8l2 2 3-4 2 3 3-2"/></svg>
  ),
  pin: (p = {}) => (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 22s7-7 7-12a7 7 0 10-14 0c0 5 7 12 7 12z"/><circle cx="12" cy="10" r="2.5"/></svg>
  ),
  plus: (p = {}) => (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 5v14M5 12h14"/></svg>
  ),
  filter: (p = {}) => (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M3 5h18l-7 9v6l-4-2v-4z"/></svg>
  ),
  dash: (p = {}) => (
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="3" y="3" width="8" height="8" rx="1.5"/><rect x="13" y="3" width="8" height="8" rx="1.5"/><rect x="3" y="13" width="8" height="8" rx="1.5"/><rect x="13" y="13" width="8" height="8" rx="1.5"/></svg>
  ),
  chart: (p = {}) => (
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M3 19V5M3 19h18"/><path d="M7 15l4-4 3 3 6-6"/></svg>
  ),
  wifi: (p = {}) => (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M2 9c6-5 14-5 20 0"/><path d="M5 13c4-3 10-3 14 0"/><path d="M8 17c2-1 6-1 8 0"/><circle cx="12" cy="20" r="1" fill="currentColor"/></svg>
  ),
  camera: (p = {}) => (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M3 8h3l2-3h8l2 3h3v11H3z"/><circle cx="12" cy="13" r="3.5"/></svg>
  ),
  alert: (p = {}) => (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 3l10 17H2z"/><path d="M12 10v4"/><circle cx="12" cy="17" r="0.5" fill="currentColor"/></svg>
  ),
  check: (p = {}) => (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M5 12l5 5L20 7"/></svg>
  ),
  refresh: (p = {}) => (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M3 12a9 9 0 0115-6.7L21 8M21 3v5h-5M21 12a9 9 0 01-15 6.7L3 16M3 21v-5h5"/></svg>
  ),
  signal: (p = {}) => (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" {...p}><path d="M4 19v-3M9 19v-7M14 19v-11M19 19v-15"/></svg>
  ),
  qr: (p = {}) => (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><path d="M14 14h3v3h-3zM18 18h3v3h-3z"/></svg>
  ),
  exit: (p = {}) => (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M15 4h4v16h-4"/><path d="M10 8l-4 4 4 4M6 12h9"/></svg>
  ),
  dots: (p = {}) => (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor" {...p}><circle cx="5" cy="12" r="1.6"/><circle cx="12" cy="12" r="1.6"/><circle cx="19" cy="12" r="1.6"/></svg>
  ),
  doc: (p = {}) => (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M6 3h9l4 4v14H6z"/><path d="M15 3v4h4M9 12h6M9 16h6"/></svg>
  ),
  share: (p = {}) => (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="6" cy="12" r="2.5"/><circle cx="18" cy="6" r="2.5"/><circle cx="18" cy="18" r="2.5"/><path d="M8 11l8-4M8 13l8 4"/></svg>
  ),
  flask: (p = {}) => (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M10 3v6L4 20a1 1 0 001 1h14a1 1 0 001-1l-6-11V3"/><path d="M9 3h6M7 15h10"/></svg>
  ),
  shield: (p = {}) => (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 3l8 3v6c0 5-3.5 8.5-8 9-4.5-.5-8-4-8-9V6z"/></svg>
  ),
  sun: (p = {}) => (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4 12H2M22 12h-2M5 5l1.5 1.5M17.5 17.5L19 19M19 5l-1.5 1.5M6.5 17.5L5 19"/></svg>
  ),
  moon: (p = {}) => (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M21 13a8 8 0 11-10-10 6 6 0 0010 10z"/></svg>
  ),
  google: (p = {}) => (
    <svg width="16" height="16" viewBox="0 0 24 24" {...p}><path d="M21.6 12.2c0-.7-.1-1.3-.2-2H12v3.9h5.4c-.2 1.3-1 2.4-2 3.1v2.6h3.4c2-1.8 3-4.5 3-7.6z" fill="#4285F4"/><path d="M12 22c2.7 0 5-.9 6.7-2.4l-3.4-2.6c-.9.6-2.1 1-3.3 1-2.6 0-4.8-1.7-5.5-4H3v2.6A10 10 0 0012 22z" fill="#34A853"/><path d="M6.5 13.9a6 6 0 010-3.8V7.5H3a10 10 0 000 9z" fill="#FBBC04"/><path d="M12 6c1.5 0 2.8.5 3.8 1.5l2.9-2.9A10 10 0 003 7.5l3.5 2.7c.7-2.3 2.9-4 5.5-4z" fill="#EA4335"/></svg>
  ),
};

// ====================== Wireframe primitives ======================
function StatusBar() {
  return (
    <div className="statusbar">
      <span className="mono">9:41</span>
      <div className="right">
        <svg width="16" height="10" viewBox="0 0 16 10" fill="none"><path d="M1 8h2M5 6h2M9 4h2M13 2h2" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/></svg>
        <svg width="14" height="10" viewBox="0 0 14 10" fill="none"><path d="M1 9c4-6 8-6 12 0" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" fill="none"/></svg>
        <svg width="24" height="11" viewBox="0 0 24 11" fill="none">
          <rect x="0.5" y="0.5" width="20" height="10" rx="2.5" stroke="currentColor" />
          <rect x="2" y="2" width="16" height="7" rx="1.2" fill="currentColor"/>
          <rect x="21" y="3.5" width="2" height="4" rx="1" fill="currentColor"/>
        </svg>
      </div>
    </div>
  );
}

function ScreenHeader({ title, sub, onBack, right, big }) {
  return (
    <div className="wf-h" style={{ paddingTop: big ? 18 : 12 }}>
      <div style={{ display: "flex", flexDirection: "column", gap: 2, minWidth: 0 }}>
        {onBack && <div className="back" onClick={onBack}><I.back /> Back</div>}
        <div className="title" style={{ fontSize: big ? 26 : 20 }}>{title}</div>
        {sub && <div className="sub">{sub}</div>}
      </div>
      {right && <div style={{ display: "flex", gap: 8 }}>{right}</div>}
    </div>
  );
}

function Field({ icon, label, value, focus, suffix, onClick }) {
  return (
    <div className={"wf-field" + (focus ? " focus" : "") + (value ? " filled" : "")} onClick={onClick} style={{ cursor: onClick ? "pointer" : "default" }}>
      {icon && <span className="dim">{icon}</span>}
      <span style={{ flex: 1 }}>{value || label}</span>
      {suffix}
    </div>
  );
}

function Btn({ children, variant = "primary", onClick, full, sm, style }) {
  return (
    <div
      className={"wf-btn " + variant + (sm ? " sm" : "")}
      onClick={onClick}
      style={{ flex: full ? 1 : "none", ...(style || {}) }}
    >
      {children}
    </div>
  );
}

function Pill({ children, variant = "" }) {
  return <span className={"wf-pill " + variant}>{children}</span>;
}

function StatusPill({ status }) {
  if (status === "ok") return <Pill variant="ok"><span className="dot" /> Normal</Pill>;
  if (status === "warn") return <Pill variant="warn"><span className="dot" /> Warning</Pill>;
  if (status === "crit") return <Pill variant="danger"><span className="dot" /> Critical</Pill>;
  return <Pill><span className="dot" /> {status}</Pill>;
}

// ====================== Sparkline ======================
function Spark({ data, width = 110, height = 28, color = "ink", filled = true }) {
  const max = Math.max(...data);
  const min = Math.min(...data);
  const range = max - min || 1;
  const dx = width / (data.length - 1);
  const points = data.map((v, i) => [i * dx, height - ((v - min) / range) * (height - 4) - 2]);
  const path = "M " + points.map(p => p.join(" ")).join(" L ");
  const fillPath = path + ` L ${width} ${height} L 0 ${height} Z`;
  return (
    <svg className="spark" width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
      {filled && <path d={fillPath} className="fl" />}
      <path d={path} className={"ln draw " + color} />
    </svg>
  );
}

// ====================== Heart Beat Icon (animated) ======================
function HeartIcon({ size = 18 }) {
  return (
    <span className="beat" style={{ display: "inline-grid", placeItems: "center" }}>
      <svg width={size} height={size} viewBox="0 0 24 24" fill="var(--danger)">
        <path d="M12 21s-7-4.5-9.5-9A5 5 0 0112 6a5 5 0 019.5 6c-2.5 4.5-9.5 9-9.5 9z"/>
      </svg>
    </span>
  );
}

// ====================== Live ECG track ======================
function ECGTrack() {
  return (
    <div className="ecg-track">
      <svg width="640" height="96" viewBox="0 0 640 96" className="ecg-anim">
        {[0, 320].map(off => (
          <g key={off} transform={`translate(${off}, 0)`}>
            <path
              className="trace"
              d="M0 50 L40 50 L48 50 L54 32 L60 70 L66 22 L72 70 L78 50 L120 50 L160 50 L168 50 L174 32 L180 70 L186 22 L192 70 L198 50 L240 50 L280 50 L288 50 L294 32 L300 70 L306 22 L312 70 L318 50 L320 50"
            />
          </g>
        ))}
      </svg>
    </div>
  );
}

// ====================== Phone Frame ======================
function PhoneFrame({ children }) {
  return (
    <div className="phone-shell">
      <div className="phone-screen">
        <div className="notch" />
        <StatusBar />
        {children}
      </div>
    </div>
  );
}

// ====================== Screen Stage (with transitions) ======================
function ScreenStage({ current, history, transitionType }) {
  const [stack, setStack] = useState([{ screen: current, kind: "", key: 0 }]);
  const keyRef = useRef(1);
  const prevScreen = useRef(current);

  useEffect(() => {
    if (prevScreen.current === current) return;
    const direction = transitionType || "fwd";
    const enterKls = {
      fwd: "enter-fwd", back: "enter-back", fade: "enter-fade", up: "enter-up", zoom: "enter-zoom",
    }[direction] || "enter-fwd";
    const exitKls = {
      fwd: "exit-fwd", back: "exit-back", fade: "exit-fade", up: "exit-up", zoom: "exit-zoom",
    }[direction] || "exit-fwd";
    const newKey = keyRef.current++;
    setStack((s) => {
      const last = s[s.length - 1];
      return [
        { ...last, kind: exitKls, leaving: true },
        { screen: current, kind: enterKls, key: newKey },
      ];
    });
    prevScreen.current = current;
    const t = setTimeout(() => {
      setStack((s) => s.filter((x) => !x.leaving).map(x => ({ ...x, kind: "" })));
    }, 460);
    return () => clearTimeout(t);
  }, [current]);

  return (
    <div className="screen-body">
      {stack.map((s) => (
        <div key={s.key} className={"page " + s.kind}>
          {s.screen}
        </div>
      ))}
    </div>
  );
}

// ====================== Bottom Nav ======================
function BottomNav({ tab, onTab }) {
  const tabs = [
    { id: "dashboard", label: "Dashboard", icon: <I.dash /> },
    { id: "trends", label: "Trends", icon: <I.chart /> },
    { id: "devices", label: "Devices", icon: <I.device /> },
    { id: "profile", label: "Profile", icon: <I.user /> },
  ];
  return (
    <div className="bnav">
      {tabs.map(t => (
        <div key={t.id} className={"tab " + (tab === t.id ? "active" : "")} onClick={() => onTab(t.id)}>
          <div className="ico">{t.icon}</div>
          <span>{t.label}</span>
        </div>
      ))}
    </div>
  );
}

// ====================== Vital Card (used on dashboard) ======================
function VitalCard({ kind, value, unit, label, status, spark, large }) {
  const iconMap = {
    hr: <HeartIcon size={18} />,
    spo2: <span style={{ color: "var(--info)" }}><I.drop /></span>,
    rr:  <span style={{ color: "#5a3da3" }}><I.lung /></span>,
    temp: <span style={{ color: "var(--warn)" }}><I.temp /></span>,
    bp:  <span style={{ color: "#0a6f4d" }}><I.bp /></span>,
  };
  const isRR = kind === "rr";
  const isSpO2 = kind === "spo2";
  return (
    <div className={"wf-box " + (isRR ? "breath" : "")} style={{ padding: 14, position: "relative", overflow: "hidden" }}>
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
        <div className="ripple-wrap" style={{ width: 28, height: 28, border: "1.2px solid var(--line)", borderRadius: 8, display: "grid", placeItems: "center", position: "relative" }}>
          {iconMap[kind]}
          {isSpO2 && <><span className="ripple" /><span className="ripple r2" /></>}
        </div>
        <StatusPill status={status} />
      </div>
      {spark && (
        <div style={{ margin: "10px 0 6px" }}>
          <Spark data={spark} width={large ? 320 : 130} height={26} color={
            kind === "hr" ? "danger" : kind === "spo2" ? "info" : kind === "temp" ? "warn" : "accent"
          } />
        </div>
      )}
      <div style={{ display: "flex", alignItems: "baseline", gap: 6, marginTop: 4 }}>
        <span className="mono" style={{ fontSize: 28, fontWeight: 800, letterSpacing: "-0.5px" }}>
          <span className="tick up" key={String(value)}>{value}</span>
        </span>
        <span style={{ fontSize: 11, color: "var(--ink-4)", letterSpacing: 0.6, textTransform: "uppercase", fontWeight: 700 }}>{unit}</span>
      </div>
      <div style={{ fontSize: 11, color: "var(--ink-3)", marginTop: 2 }}>{label}</div>
    </div>
  );
}

// ====================== Skeleton card ======================
function SkeletonCard() {
  return (
    <div className="wf-box" style={{ padding: 14 }}>
      <div className="shimmer" style={{ height: 14, width: 80, marginBottom: 10 }} />
      <div className="shimmer" style={{ height: 26, width: 100, marginBottom: 8 }} />
      <div className="shimmer" style={{ height: 10, width: 60 }} />
    </div>
  );
}

// ====================== Export to globals ======================
Object.assign(window, {
  I, StatusBar, ScreenHeader, Field, Btn, Pill, StatusPill,
  Spark, HeartIcon, ECGTrack, PhoneFrame, ScreenStage, BottomNav,
  VitalCard, SkeletonCard,
  useState, useEffect, useRef, useMemo, useCallback,
});
