// luxury.host — Status page
// Plain inline React, mounted in luxury.host - Status.html.
//
// gh#1006 — REAL DATA. This page fetches GET {FB_BASE}/api/status (served by the
// luxury.host Fly app; recorder-backed real component health + rolling 90-day
// uptime + incident history). NO synthetic/mock data — when the recorder has
// only just started, fields are honestly empty ("collecting data"), never faked.
// Override the API origin for testing with ?fb=https://flatsbratislava-sandbox.fly.dev

const { useState, useMemo, useEffect } = React;

const FB_BASE = (() => {
  try {
    const q = new URLSearchParams(location.search).get("fb");
    if (q) {
      localStorage.setItem("status_fb_base", q);
      return q;
    }
    return localStorage.getItem("status_fb_base") || "https://luxury.host";
  } catch (e) {
    return "https://luxury.host";
  }
})();

// ──────────────────────────────────────────────────────────────────────
// ICONS
// ──────────────────────────────────────────────────────────────────────
const Icon = ({ name, size = 14 }) => {
  const p = { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.7, strokeLinecap: "round", strokeLinejoin: "round" };
  switch (name) {
    case "grid":   return <svg {...p}><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg>;
    case "code":   return <svg {...p}><path d="M16 18l6-6-6-6M8 6l-6 6 6 6"/></svg>;
    case "spark":  return <svg {...p}><path d="M12 3l2 5 5 2-5 2-2 5-2-5-5-2 5-2z"/></svg>;
    case "chat":   return <svg {...p}><path d="M3 12a8 8 0 1 1 3.6 6.7L3 21l1.3-4A8 8 0 0 1 3 12z"/></svg>;
    case "globe":  return <svg {...p}><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18"/></svg>;
    case "db":     return <svg {...p}><ellipse cx="12" cy="6" rx="8" ry="3"/><path d="M4 6v12c0 1.7 3.6 3 8 3s8-1.3 8-3V6M4 12c0 1.7 3.6 3 8 3s8-1.3 8-3"/></svg>;
    case "check":  return <svg {...p}><path d="M5 12l5 5L20 7"/></svg>;
    case "bell":   return <svg {...p}><path d="M6 18h12l-2-2v-5a4 4 0 0 0-8 0v5l-2 2zM10 21h4"/></svg>;
    case "rss":    return <svg {...p}><path d="M4 11a9 9 0 0 1 9 9M4 4a16 16 0 0 1 16 16"/><circle cx="5" cy="19" r="1.5"/></svg>;
    case "shield": return <svg {...p}><path d="M12 2l8 4v6c0 5-3.5 9-8 10-4.5-1-8-5-8-10V6l8-4z"/></svg>;
    default: return null;
  }
};

// Component id → icon.
const COMP_ICON = {
  application: "grid",
  database: "db",
  automation: "spark",
  messaging: "chat",
  marketing: "globe",
};

const STATE_LABEL = {
  ok: "Operational",
  degraded: "Degraded",
  major: "Major outage",
  unknown: "No data yet",
};

const OVERALL_CONFIG = {
  ok:       { eyebrow: "Live · recorded every 5 min", title: "All systems", emph: "operational." },
  degraded: { eyebrow: "Live · monitoring an issue",  title: "Some systems", emph: "degraded." },
  major:    { eyebrow: "Live · active incident",       title: "We're working", emph: "on it." },
};

function fmtDate(iso) {
  if (!iso) return "—";
  try {
    return new Date(iso).toLocaleString("en-GB", {
      day: "2-digit", month: "short", hour: "2-digit", minute: "2-digit",
      timeZone: "Europe/Bratislava",
    }) + " CET";
  } catch (e) { return iso; }
}

function durationBetween(a, b) {
  const ms = (b ? new Date(b) : new Date()) - new Date(a);
  if (!(ms > 0)) return "—";
  const mins = Math.round(ms / 60000);
  if (mins < 60) return mins + "m";
  const h = Math.floor(mins / 60), m = mins % 60;
  if (h < 24) return m ? `${h}h ${m}m` : `${h}h`;
  const d = Math.floor(h / 24);
  return `${d}d ${h % 24}h`;
}

// ──────────────────────────────────────────────────────────────────────
// HERO
// ──────────────────────────────────────────────────────────────────────
function StatusHero({ data }) {
  const overall = data.overall || "ok";
  const config = OVERALL_CONFIG[overall] || OVERALL_CONFIG.ok;

  const withData = (data.components || []).filter((c) => c.uptimePct != null);
  const avgUptime = withData.length
    ? (withData.reduce((s, c) => s + c.uptimePct, 0) / withData.length)
    : null;
  const active = (data.incidents || []).filter((i) => i.state === "ongoing").length;
  const cutoff = Date.now() - 30 * 864e5;
  const resolved30 = (data.incidents || []).filter(
    (i) => i.state === "resolved" && i.resolvedAt && new Date(i.resolvedAt) >= cutoff
  ).length;
  const monitored = (data.components || []).filter((c) => c.state !== "unknown").length;

  const eyebrow = data.hasData ? config.eyebrow : "Live · collecting first data";

  return (
    <header className={`status-hero is-${overall}`}>
      <div className="status-hero-inner">
        <div className="status-hero-row">
          <div className="status-hero-l">
            <div className="status-pulse">
              <Icon name={overall === "ok" ? "check" : "shield"} size={26} />
            </div>
            <div className="status-hero-text">
              <span className="status-hero-eyebrow">{eyebrow}</span>
              <h1 className="status-hero-h">
                {data.hasData ? config.title : "Monitoring"}{" "}
                <em>{data.hasData ? config.emph : "starting up."}</em>
              </h1>
            </div>
          </div>
          <div className="status-hero-r">
            <a className="status-hero-pill"><Icon name="bell" size={13} /> Subscribe</a>
            <a className="status-hero-pill"><Icon name="rss" size={13} /> RSS</a>
          </div>
        </div>
        <div className="status-hero-stats">
          <div className="status-hero-stat">
            <div className="n">{avgUptime == null ? "—" : avgUptime.toFixed(2) + "%"}</div>
            <div className="l">90-day uptime</div>
          </div>
          <div className="status-hero-stat">
            <div className="n">{active}</div>
            <div className="l">active incident{active === 1 ? "" : "s"}</div>
          </div>
          <div className="status-hero-stat">
            <div className="n">{resolved30}</div>
            <div className="l">resolved · last 30 days</div>
          </div>
          <div className="status-hero-stat">
            <div className="n">{monitored}</div>
            <div className="l">components monitored</div>
          </div>
        </div>
      </div>
    </header>
  );
}

// ──────────────────────────────────────────────────────────────────────
// SERVICE LIST
// ──────────────────────────────────────────────────────────────────────
function UptimeBar({ bars }) {
  if (!bars || bars.length === 0) {
    return (
      <div className="uptime" aria-label="90-day uptime">
        <span style={{ flex: 1, textAlign: "left", fontSize: 11, color: "var(--ink-3)", background: "none" }}>
          No history recorded yet — the 90-day bar fills as data accumulates.
        </span>
      </div>
    );
  }
  return (
    <div className="uptime" aria-label="90-day uptime">
      {bars.map((b, i) => {
        const cls = b.state === "ok" ? "" : b.state === "none" ? "" : `is-${b.state}`;
        const style = b.state === "none" ? { background: "rgba(0,0,0,0.08)" } : undefined;
        const label =
          b.state === "none" ? "No data" :
          b.state === "ok" ? "No incidents" : b.state;
        return <span key={i} className={cls} style={style} title={`${b.day} · ${label}`} />;
      })}
    </div>
  );
}

function ServiceRow({ c }) {
  const label = STATE_LABEL[c.state] || "Operational";
  const pillState = c.state === "unknown" ? "maint" : c.state;
  return (
    <div className="status-row">
      <div className="status-row-l">
        <div className="status-row-name">
          <span className="iglyph"><Icon name={COMP_ICON[c.id] || "grid"} /></span>
          {c.name}
        </div>
        <div className="status-row-desc">
          {c.desc}{c.detail ? ` · ${c.detail}` : ""}
        </div>
      </div>
      <div className="status-uptime-meta">
        <div className="label">
          <span>90-day uptime</span>
          <strong>{c.uptimePct == null ? "—" : c.uptimePct.toFixed(2) + "%"}</strong>
        </div>
        <UptimeBar bars={c.bars} />
      </div>
      <span className={`status-pill is-${pillState}`}>
        <span className="d" />
        {label}
      </span>
    </div>
  );
}

function ServiceList({ components }) {
  const known = components.filter((c) => c.state !== "unknown");
  const allOk = known.length > 0 && known.every((c) => c.state === "ok");
  return (
    <section className="status-group">
      <header className="status-group-head">
        <h2 className="status-group-h">Services</h2>
        <span className="status-group-meta">
          <span className="dot" />
          {known.length === 0 ? "Collecting data" : allOk ? "All operational" : "Mixed status"}
        </span>
      </header>
      {components.map((c) => <ServiceRow key={c.id} c={c} />)}
    </section>
  );
}

// ──────────────────────────────────────────────────────────────────────
// INCIDENTS
// ──────────────────────────────────────────────────────────────────────
function IncidentCard({ incident, showResolved }) {
  const sev = incident.severity || "degraded";
  const sevLabel = sev === "major" ? "Major" : sev === "degraded" ? "Degraded" : "Incident";
  return (
    <article className={`incident is-${incident.state}`}>
      <header className="incident-head">
        <h3 className="incident-h">{incident.title}</h3>
        <span className={`status-pill is-${sev}`}>
          <span className="d" />
          {sevLabel}
        </span>
      </header>
      <div className="incident-meta">
        <span><strong>Started</strong> {fmtDate(incident.startedAt)}</span>
        <span><strong>Duration</strong> {durationBetween(incident.startedAt, incident.resolvedAt)}</span>
        <span><strong>Affecting</strong> {incident.componentName}</span>
        {showResolved && incident.resolvedAt && (
          <span><strong>Resolved</strong> {fmtDate(incident.resolvedAt)}</span>
        )}
      </div>
    </article>
  );
}

function ActiveIncidents({ incidents }) {
  const active = incidents.filter((i) => i.state === "ongoing");
  if (active.length === 0) {
    return (
      <div className="incident-empty">
        <div className="check"><Icon name="check" size={20} /></div>
        <div>No active incidents. <em>Everything looks good.</em></div>
      </div>
    );
  }
  return active.map((i) => <IncidentCard key={i.id} incident={i} />);
}

function PastIncidents({ incidents }) {
  const resolved = incidents.filter((i) => i.state === "resolved");
  if (resolved.length === 0) {
    return (
      <div className="incident-empty" style={{ fontSize: 15 }}>
        <em>No incidents recorded in the last 90 days.</em>
      </div>
    );
  }
  return resolved.map((i) => (
    <IncidentCard key={i.id} incident={i} showResolved />
  ));
}

// ──────────────────────────────────────────────────────────────────────
// LEGEND / SUBSCRIBE
// ──────────────────────────────────────────────────────────────────────
function Legend() {
  const items = [
    ["#5fa86a", "Operational"],
    ["#f5b945", "Degraded"],
    ["#c43575", "Major outage"],
    ["rgba(0,0,0,0.08)", "No data"],
  ];
  return (
    <div className="status-legend">
      <span>Past 90 days · </span>
      {items.map(([c, l]) => (
        <span className="lg-item" key={l}>
          <span className="lg-swatch" style={{ background: c }} />
          {l}
        </span>
      ))}
    </div>
  );
}

function Subscribe() {
  const [email, setEmail] = useState("");
  const [sent, setSent] = useState(false);
  return (
    <section className="subscribe-box">
      <div>
        <h3>Get <em>notified</em> of every change.</h3>
        <p>Email, RSS, or webhook. We post here first when anything is off — before you notice it yourself.</p>
      </div>
      <div className="subscribe-actions">
        <input
          type="email"
          placeholder="you@email.com"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          style={{
            padding: "10px 18px",
            background: "rgba(255,255,255,0.85)",
            border: "1px solid var(--glass-border)",
            color: "var(--ink)",
            borderRadius: 999,
            fontFamily: "var(--f-sans)", fontSize: 13,
            outline: "none", minWidth: 220,
          }}
        />
        <button
          className="btn btn-pri"
          onClick={() => { if (email.trim()) { setSent(true); setEmail(""); setTimeout(() => setSent(false), 2400); } }}
        >
          {sent ? "Subscribed ✓" : "Email me"}
        </button>
        <button className="btn btn-glass"><Icon name="rss" size={13} /> RSS</button>
      </div>
    </section>
  );
}

// ──────────────────────────────────────────────────────────────────────
// APP
// ──────────────────────────────────────────────────────────────────────
function StatusPage() {
  const [data, setData] = useState(null);
  const [err, setErr] = useState(false);

  useEffect(() => {
    let cancelled = false;
    const load = () => {
      fetch(FB_BASE + "/api/status", { headers: { Accept: "application/json" } })
        .then((r) => { if (!r.ok) throw new Error("http " + r.status); return r.json(); })
        .then((d) => { if (!cancelled) { setData(d); setErr(false); } })
        .catch(() => { if (!cancelled) setErr(true); });
    };
    load();
    const iv = setInterval(load, 60000); // auto-refresh every 60s
    return () => { cancelled = true; clearInterval(iv); };
  }, []);

  if (err && !data) {
    return (
      <div className="incident-empty" style={{ marginTop: 40 }}>
        <div><em>Status data is temporarily unavailable.</em> Retrying…</div>
      </div>
    );
  }
  if (!data) {
    return (
      <div className="incident-empty" style={{ marginTop: 40 }}>
        <div>Loading live status…</div>
      </div>
    );
  }

  const components = data.components || [];
  const incidents = data.incidents || [];

  return (
    <>
      <StatusHero data={data} />

      <section className="status-section">
        <header className="status-section-h">
          <h2>Active <em>incident</em></h2>
          <span className="meta">Live · refreshes every 60s</span>
        </header>
        <ActiveIncidents incidents={incidents} />
      </section>

      <section className="status-section">
        <header className="status-section-h">
          <h2><em>Service</em> health</h2>
          <span className="meta">90-day window</span>
        </header>
        <ServiceList components={components} />
        <Legend />
      </section>

      <section className="status-section">
        <header className="status-section-h">
          <h2>Past <em>incidents</em></h2>
          <span className="meta">Last 90 days</span>
        </header>
        <PastIncidents incidents={incidents} />
      </section>

      <Subscribe />
    </>
  );
}

window.StatusPage = StatusPage;
