/* global React */
// ── Shared atoms, icons, and the HP namespace ──────────────────
// All components are exposed on window.HP for cross-file access.

// ── Logo mark ─────────────────────────────────────────────────
const Logo = ({ size = 22 }) => (
  <img
    src="assets/logo.png"
    alt="HousingPulse"
    style={{
      width: size + 8,
      height: size + 8,
      objectFit: "contain",
      display: "inline-block",
      flexShrink: 0,
      verticalAlign: "middle",
    }}
  />
);

// ── Inline icon set (Lucide-style, 1.6px stroke) ─────────────
const Icon = {
  Search: ({ size = 18 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/>
    </svg>
  ),
  Lock: ({ size = 16 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <rect x="4" y="11" width="16" height="10" rx="2"/><path d="M8 11V7a4 4 0 0 1 8 0v4"/>
    </svg>
  ),
  Check: ({ size = 14 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
      <polyline points="20 6 9 17 4 12"/>
    </svg>
  ),
  Arrow: ({ size = 14 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/>
    </svg>
  ),
  Phone: ({ size = 16 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <rect x="5" y="2" width="14" height="20" rx="2"/><line x1="12" y1="18" x2="12.01" y2="18" strokeWidth="2"/>
    </svg>
  ),
  QrCode: ({ size = 16 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <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 14h1v1h-1z M16 14h1v1h-1z M14 16h1v1h-1z M16 16h1v1h-1z M18 14h3v3h-3z M14 18h3v3h-3z M18 18h3v3h-3z"/>
    </svg>
  ),
  Bell: ({ size = 16 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/>
    </svg>
  ),
  Bookmark: ({ size = 16 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <path d="m19 21-7-4-7 4V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/>
    </svg>
  ),
  Share: ({ size = 16 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"/>
      <polyline points="16 6 12 2 8 6"/><line x1="12" y1="2" x2="12" y2="15"/>
    </svg>
  ),
  Refresh: ({ size = 14 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/>
      <path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/>
      <path d="M3 21v-5h5"/>
    </svg>
  ),
  Shield: ({ size = 16 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>
      <polyline points="9 12 11 14 15 10"/>
    </svg>
  ),
  AlertTriangle: ({ size = 16 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <path d="m10.29 3.86-8.18 14A2 2 0 0 0 3.82 21h16.36a2 2 0 0 0 1.71-3.14l-8.18-14a2 2 0 0 0-3.42 0z"/>
      <line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17" strokeWidth="2"/>
    </svg>
  ),
  Spinner: ({ size = 16 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" className="spin">
      <path d="M21 12a9 9 0 1 1-6.219-8.56"/>
    </svg>
  ),
  Home: ({ size = 16 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <path d="M3 9.5L12 3l9 6.5V20a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V9.5z"/>
      <path d="M9 21V12h6v9"/>
    </svg>
  ),
  Map: ({ size = 16 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <polygon points="1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6"/>
      <line x1="8" y1="2" x2="8" y2="18"/><line x1="16" y1="6" x2="16" y2="22"/>
    </svg>
  ),
  Grid: ({ size = 16 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <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"/><rect x="14" y="14" width="7" height="7"/>
    </svg>
  ),
};

// ── Tag atom ─────────────────────────────────────────────────
const Tag = ({ tone = "none", solid, dot, children, style }) => (
  <span className={`tag ${solid ? "tag--solid-high" : `tag--${tone}`}`} style={style}>
    {dot && <span className="tag-dot"/>}
    {children}
  </span>
);

// ── Sparkline ────────────────────────────────────────────────
const Spark = ({ data, color = "#0B4FA6", w = 56, h = 18 }) => {
  const max = Math.max(...data), min = Math.min(...data), span = max - min || 1;
  const step = w / (data.length - 1);
  const pts = data.map((v, i) => `${(i * step).toFixed(1)},${(h - ((v - min) / span) * (h - 2) - 1).toFixed(1)}`);
  return (
    <svg viewBox={`0 0 ${w} ${h}`} width={w} height={h}>
      <path d={`M${pts.join(" L")} L${w},${h} L0,${h} Z`} fill={color} opacity="0.12"/>
      <path d={`M${pts.join(" L")}`} fill="none" stroke={color} strokeWidth="1.4"/>
    </svg>
  );
};

// ── Risk ring (donut score) ────────────────────────────────
const RiskRing = ({ score, size = 56, color = "#B5261B" }) => {
  const sw = Math.max(4, size * 0.072);
  const r = (size - sw * 2) / 2;
  const c = 2 * Math.PI * r;
  const off = c - (score / 100) * c;
  const fs = Math.round(size * 0.22);
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
      <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="#F4F2EE" strokeWidth={sw}/>
      <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={color} strokeWidth={sw}
        strokeDasharray={c} strokeDashoffset={off} strokeLinecap="round"
        transform={`rotate(-90 ${size/2} ${size/2})`}/>
      <text x={size/2} y={size/2 + fs * 0.35} textAnchor="middle"
        style={{ fontFamily: "system-ui, sans-serif", fontWeight: 800, fontSize: fs, fill: color, fontVariantNumeric: "tabular-nums" }}>
        {score}
      </text>
    </svg>
  );
};

// ── Top app bar — landing-style fixed glass nav ───────────────
const AppBar = ({ query, onQuery, onSearch, onHome, onMap, onDashboard, onSaved }) => {
  const [scrolled, setScrolled] = React.useState(false);
  React.useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 20);
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  return (
    <header style={{
      position: "fixed", top: 0, left: 0, right: 0, zIndex: 100,
      display: "grid", gridTemplateColumns: "1fr auto 1fr", alignItems: "center",
      padding: scrolled ? "12px clamp(16px,3.5vw,52px)" : "18px clamp(16px,3.5vw,52px)",
      background: "rgba(237,228,208,0.94)",
      backdropFilter: "blur(20px) saturate(180%)",
      WebkitBackdropFilter: "blur(20px) saturate(180%)",
      borderBottom: "1px solid rgba(200,149,42,0.22)",
      boxShadow: scrolled ? "0 2px 20px rgba(42,31,20,0.10)" : "none",
      transition: "padding 240ms ease, box-shadow 240ms ease",
    }}>
      <div style={{ display: "flex", alignItems: "center" }}>
        <span onClick={onHome} style={{
          display: "flex", alignItems: "center", gap: 9, cursor: "pointer",
          fontFamily: "var(--hp-font-sans)", fontSize: 17, fontWeight: 700,
          color: "var(--hp-ink)", letterSpacing: "-0.01em", userSelect: "none",
        }}>
          <Logo size={20}/>
          Housing<span style={{ color: "var(--hp-action)" }}>Pulse</span>
        </span>
      </div>
      <nav style={{ display: "flex", gap: "clamp(14px,2.5vw,32px)", alignItems: "center" }}>
        {[["Map Search", onMap], ["Dashboard", onDashboard], ["Saved", onSaved]].map(([lbl, fn]) => (
          <a key={lbl} onClick={fn} style={{
            fontFamily: "var(--hp-font-sans)", fontSize: 15, fontWeight: 500,
            color: "var(--hp-ink)", cursor: "pointer", userSelect: "none",
            letterSpacing: "-0.005em", textDecoration: "none",
            transition: "color 160ms ease",
          }}
          onMouseEnter={e => e.currentTarget.style.color = "var(--hp-action)"}
          onMouseLeave={e => e.currentTarget.style.color = "var(--hp-ink)"}>
            <span style={{ whiteSpace: "nowrap" }}>{lbl}</span>
          </a>
        ))}
      </nav>
      <div style={{ display: "flex", alignItems: "center", gap: 12, justifyContent: "flex-end" }}>
        <form onSubmit={(e) => { e.preventDefault(); onSearch && onSearch(query); }}
          className="hp-nav-search"
          style={{
            display: "flex", alignItems: "center", gap: 8,
            background: "rgba(42,31,20,0.06)", border: "1px solid rgba(200,149,42,0.25)",
            borderRadius: 8, padding: "7px 12px",
          }}>
          <Icon.Search size={14}/>
          <input placeholder="Search address…" value={query}
            onChange={(e) => onQuery && onQuery(e.target.value)}
            style={{
              all: "unset", fontFamily: "var(--hp-font-sans)", fontSize: 13,
              color: "var(--hp-ink)", width: "clamp(80px,10vw,160px)",
            }}/>
        </form>
        <a href="https://apps.apple.com/us/app/housingpulse/id6763149818"
          target="_blank" rel="noopener noreferrer"
          style={{
            display: "inline-flex", alignItems: "center", gap: 6,
            background: "var(--hp-ink)", color: "#FAF5EB",
            fontFamily: "var(--hp-font-sans)", fontSize: 13, fontWeight: 600,
            padding: "9px 18px", borderRadius: 8, textDecoration: "none",
            letterSpacing: "-0.005em", whiteSpace: "nowrap",
            transition: "background 160ms ease",
          }}
          onMouseEnter={e => e.currentTarget.style.background = "#3D2B1F"}
          onMouseLeave={e => e.currentTarget.style.background = "var(--hp-ink)"}
        >
          <svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.8-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M13 3.5c.73-.83 1.94-1.46 2.94-1.5.13 1.17-.34 2.35-1.04 3.19-.69.85-1.83 1.51-2.95 1.42-.15-1.15.41-2.35 1.05-3.11z"/></svg>
          <span className="hp-nav-dl">Download App</span>
        </a>
      </div>
    </header>
  );
};

// ── Shared building fixture ───────────────────────────────
const BUILDING = {
  address:        "8855 Bay Parkway",
  subline:        "Bensonhurst, Brooklyn NY 11214",
  bin:            "3170043",
  bbl:            "3064710090",
  stories:        10,
  units:          164,
  year:           1958,
  classification: "D4 — Elevator, 100+ units",
  riskScore:      12,
  violationsOpen: 0,
  violationsC:    2,
  complaintsOpen: 1,
  permitsActive:  2,
  zoning:         "R6",
  zoningDesc:     "Mid-density residential",
  far:            7.08,
  farMax:         2.43,
  lotArea:        18970,
  buildingArea:   134280,
};

// ── API base URL ─────────────────────────────────────────
// Production: set to your deployed Cloudflare Worker URL
// e.g. https://housingpulse-worker.<subdomain>.workers.dev
// or custom domain: https://api.nychousingpulse.com
const API_BASE = typeof window !== 'undefined' && window.location.hostname !== 'localhost'
  ? 'https://housingpulse-worker.explainthis-ai.workers.dev'
  : 'http://localhost:8787';

// ── Responsive nav styles ────────────────────────────────
if (typeof document !== "undefined" && !document.getElementById("hp-nav-css")) {
  const s = document.createElement("style");
  s.id = "hp-nav-css";
  s.textContent = `
    .hp-nav-search { display: flex; }
    .hp-nav-dl span { display: inline; }
    @media (max-width: 900px) {
      .hp-nav-search { display: none !important; }
      .hp-nav-dl span { display: none !important; }
    }
  `;
  document.head.appendChild(s);
}

// ── Export namespace ─────────────────────────────────────
window.HP = { Logo, Icon, Tag, Spark, RiskRing, AppBar, BUILDING, API_BASE };
