// relax.host — Status page
// Plain inline React, mounted in relax.host - Status.html.
// Heavy use of glassmorphic cards, the Daylight palette, and a custom
// status color set (sage / gold / peach-dark / coral-deep / lavender)
// layered on top of the brand's existing tokens.

const { useState, useMemo } = React;

// ──────────────────────────────────────────────────────────────────────
// DATA — realistic 90-day uptime synthesis. Each service has a base
// uptime profile and a few historical incident dips so the bar chart
// tells a real story instead of being flat-green.
// ──────────────────────────────────────────────────────────────────────
function makeUptime(profile) {
  // profile: { incidents: [{day, severity}], baseSeverity? }
  const arr = [];
  for (let i = 0; i < 90; i++) {
    const inc = profile.incidents.find((x) => x.day === i);
    arr.push(inc ? inc.severity : (profile.base || "ok"));
  }
  return arr;
}

const SERVICES = [
  {
    id: "core",
    name: "Core platform",
    services: [
      { id: "dashboard", name: "Host dashboard",       icon: "grid",   desc: "app.relax.host",          uptime: makeUptime({ incidents: [{ day: 12, severity: "partial" }, { day: 47, severity: "degraded" }] }), uptimePct: "99.98%", state: "ok" },
      { id: "api",       name: "Public API",           icon: "code",   desc: "api.relax.host",          uptime: makeUptime({ incidents: [{ day: 32, severity: "degraded" }] }), uptimePct: "99.99%", state: "ok" },
      { id: "agent",     name: "AI agent · drafting",  icon: "spark",  desc: "the autonomous worker",  uptime: makeUptime({ incidents: [{ day: 18, severity: "partial" }, { day: 55, severity: "partial" }, { day: 84, severity: "degraded" }] }), uptimePct: "99.92%", state: "degraded" },
      { id: "auth",      name: "Authentication",       icon: "lock",   desc: "OAuth + sessions",       uptime: makeUptime({ incidents: [] }), uptimePct: "100.00%", state: "ok" },
    ],
  },
  {
    id: "ota",
    name: "Channel integrations",
    services: [
      { id: "airbnb",  name: "Airbnb sync",       icon: "house",  desc: "reservations · messages · pricing", uptime: makeUptime({ incidents: [{ day: 4, severity: "major" }, { day: 5, severity: "major" }, { day: 6, severity: "partial" }, { day: 22, severity: "degraded" }, { day: 71, severity: "degraded" }] }), uptimePct: "99.78%", state: "ok" },
      { id: "booking", name: "Booking.com sync",  icon: "globe",  desc: "reservations · pricing",            uptime: makeUptime({ incidents: [{ day: 38, severity: "partial" }, { day: 39, severity: "degraded" }, { day: 60, severity: "degraded" }] }), uptimePct: "99.87%", state: "ok" },
      { id: "vrbo",    name: "VRBO sync",         icon: "globe",  desc: "reservations · pricing",            uptime: makeUptime({ incidents: [{ day: 28, severity: "partial" }] }), uptimePct: "99.93%", state: "ok" },
      { id: "nuki",    name: "Nuki + TTLock",     icon: "key",    desc: "smart lock codes",                  uptime: makeUptime({ incidents: [{ day: 64, severity: "degraded" }] }), uptimePct: "99.96%", state: "ok" },
    ],
  },
  {
    id: "ops",
    name: "Operations",
    services: [
      { id: "messages",   name: "Guest messaging",      icon: "chat",     desc: "inbound + AI draft pipeline",   uptime: makeUptime({ incidents: [{ day: 50, severity: "degraded" }] }), uptimePct: "99.97%", state: "ok" },
      { id: "cleaning",   name: "Cleaning coordination",icon: "broom",    desc: "schedules + magic-link app",    uptime: makeUptime({ incidents: [{ day: 78, severity: "maint" }] }), uptimePct: "99.99%", state: "ok" },
      { id: "invoices",   name: "Invoice generation",   icon: "doc",      desc: "PDFs · monthly close exports",   uptime: makeUptime({ incidents: [{ day: 41, severity: "partial" }, { day: 88, severity: "maint" }] }), uptimePct: "99.95%", state: "ok" },
      { id: "expenses",   name: "Expense AI · receipts",icon: "scan",     desc: "OCR + categorization",          uptime: makeUptime({ incidents: [{ day: 11, severity: "degraded" }, { day: 67, severity: "degraded" }] }), uptimePct: "99.94%", state: "ok" },
    ],
  },
  {
    id: "infra",
    name: "Infrastructure",
    services: [
      { id: "web",     name: "Marketing site",       icon: "globe",  desc: "relax.host",                        uptime: makeUptime({ incidents: [] }), uptimePct: "100.00%", state: "ok" },
      { id: "docs",    name: "Docs + developers",    icon: "book",   desc: "docs.relax.host",                   uptime: makeUptime({ incidents: [{ day: 26, severity: "maint" }] }), uptimePct: "100.00%", state: "ok" },
      { id: "cdn",     name: "CDN · EU",             icon: "cloud",  desc: "image + asset edge",               uptime: makeUptime({ incidents: [{ day: 16, severity: "degraded" }] }), uptimePct: "99.99%", state: "ok" },
      { id: "db",      name: "Primary database",     icon: "db",     desc: "EU-hosted Postgres",               uptime: makeUptime({ incidents: [{ day: 73, severity: "maint" }] }), uptimePct: "100.00%", state: "ok" },
    ],
  },
];

const INCIDENTS = [
  {
    id: "i-1",
    title: "AI agent · elevated draft latency",
    state: "monitoring",
    impact: "degraded",
    affected: ["AI agent · drafting"],
    started: "May 22, 14:22 CET",
    duration: "1h 18m · ongoing",
    updates: [
      { time: "15:38 CET", label: "Monitoring", body: "Latency back within SLA on all regions. Continuing to monitor draft throughput; will mark resolved if stable through 18:00 CET." },
      { time: "15:04 CET", label: "Identified", body: "A model-provider queue was throttling our inference workers in EU-WEST. We've routed around the affected region and are gradually re-warming the pool." },
      { time: "14:22 CET", label: "Investigating", body: "We're seeing elevated p95 latency on AI draft generation. Sends are succeeding, but drafts are taking 8–12s instead of <2s. Investigating." },
    ],
  },
  {
    id: "i-2",
    title: "Airbnb sync — partial outage (EU)",
    state: "resolved",
    impact: "major",
    affected: ["Airbnb sync"],
    started: "May 18, 03:14 CET",
    duration: "1h 47m",
    updates: [
      { time: "May 18, 05:01 CET", label: "Resolved", body: "Airbnb's API has returned to baseline. All queued reservations have been synced; messages backfilled in order. No data loss." },
      { time: "May 18, 04:12 CET", label: "Monitoring", body: "Sync resumed in all EU regions. We're working through a backlog of ~4,200 reservation events; expected to drain in ~30 min." },
      { time: "May 18, 03:34 CET", label: "Identified", body: "Confirmed upstream incident on Airbnb's side affecting EU OAuth and webhooks. relax.host is queuing all events and will replay automatically once they recover." },
      { time: "May 18, 03:14 CET", label: "Investigating", body: "We're seeing 5xx errors from Airbnb's API across EU listings. Affected hosts will see delayed message and reservation sync." },
    ],
  },
];

const HISTORY = [
  {
    day: "May 16, 2026",
    incidents: [
      { id: "h-1", title: "Booking.com · delayed price pushes (EU)", impact: "degraded", duration: "42m", state: "resolved" },
    ],
  },
  {
    day: "May 11, 2026",
    incidents: [
      { id: "h-2", title: "Scheduled — database failover drill", impact: "maint", duration: "12m", state: "completed" },
    ],
  },
  {
    day: "May 5, 2026",
    incidents: [
      { id: "h-3", title: "Receipt OCR — degraded confidence on Romanian receipts", impact: "degraded", duration: "3h 22m", state: "resolved" },
    ],
  },
  {
    day: "Apr 29, 2026",
    incidents: [
      { id: "h-4", title: "Nuki integration — temporary code-generation delay", impact: "degraded", duration: "1h 4m", state: "resolved" },
    ],
  },
];

const SCHEDULED = [
  {
    id: "s-1",
    title: "Database failover · EU-WEST → EU-CENTRAL",
    when: "May 28, 2026 · 02:00–02:30 CET",
    duration: "Up to 30 min",
    impact: "Brief read-only window (<2 min). No expected message or sync delays.",
  },
];

// ──────────────────────────────────────────────────────────────────────
// 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 "lock":   return <svg {...p}><rect x="4" y="11" width="16" height="10" rx="2"/><path d="M8 11V7a4 4 0 0 1 8 0v4"/></svg>;
    case "house":  return <svg {...p}><path d="M3 11l9-8 9 8"/><path d="M5 10v10h14V10"/></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 "key":    return <svg {...p}><circle cx="8" cy="12" r="4"/><path d="M12 12h10M18 12v4M22 12v4"/></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 "broom":  return <svg {...p}><path d="M14 4l6 6M4 20l6-12 6 6L8 20H4z"/></svg>;
    case "doc":    return <svg {...p}><path d="M6 3h9l4 4v14H6z"/><path d="M14 3v5h5M9 13h6M9 17h6"/></svg>;
    case "scan":   return <svg {...p}><path d="M4 7V5a1 1 0 0 1 1-1h2M20 7V5a1 1 0 0 0-1-1h-2M4 17v2a1 1 0 0 0 1 1h2M20 17v2a1 1 0 0 1-1 1h-2M3 12h18"/></svg>;
    case "book":   return <svg {...p}><path d="M4 4a2 2 0 0 1 2-2h12v18H6a2 2 0 0 0-2 2V4z"/><path d="M4 20a2 2 0 0 1 2-2h12"/></svg>;
    case "cloud":  return <svg {...p}><path d="M17 18H7a4 4 0 0 1-1-7.9 5.5 5.5 0 0 1 10.6-2.1A4.5 4.5 0 0 1 17 18z"/></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;
  }
};

// ──────────────────────────────────────────────────────────────────────
// HERO
// ──────────────────────────────────────────────────────────────────────
function StatusHero({ overallState }) {
  const config = {
    ok:       { eyebrow: "Live · last refreshed 30 sec ago", title: "All systems", emph: "operational." },
    degraded: { eyebrow: "Live · monitoring incidents",      title: "Some services", emph: "degraded." },
    major:    { eyebrow: "Live · active major incident",     title: "We're working", emph: "on it." },
  }[overallState];

  return (
    <header className={`status-hero is-${overallState}`}>
      <div className="status-hero-inner">
        <div className="status-hero-row">
          <div className="status-hero-l">
            <div className="status-pulse">
              <Icon name={overallState === "ok" ? "check" : "shield"} size={26} />
            </div>
            <div className="status-hero-text">
              <span className="status-hero-eyebrow">{config.eyebrow}</span>
              <h1 className="status-hero-h">{config.title} <em>{config.emph}</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">99.96%</div><div className="l">90-day uptime</div></div>
          <div className="status-hero-stat"><div className="n">1</div><div className="l">active incident</div></div>
          <div className="status-hero-stat"><div className="n">12</div><div className="l">resolved · last 30 days</div></div>
          <div className="status-hero-stat"><div className="n">120 ms</div><div className="l">avg API p50</div></div>
        </div>
      </div>
    </header>
  );
}

// ──────────────────────────────────────────────────────────────────────
// SERVICE LIST
// ──────────────────────────────────────────────────────────────────────
function ServiceGroup({ group }) {
  const allOk = group.services.every((s) => s.state === "ok");
  return (
    <section className="status-group">
      <header className="status-group-head">
        <h2 className="status-group-h">{group.name}</h2>
        <span className="status-group-meta">
          <span className="dot" />
          {allOk ? "All operational" : "Mixed status"}
        </span>
      </header>
      {group.services.map((s) => <ServiceRow key={s.id} s={s} />)}
    </section>
  );
}

function ServiceRow({ s }) {
  const stateLabel = {
    ok:       "Operational",
    degraded: "Degraded",
    partial:  "Partial outage",
    major:    "Major outage",
    maint:    "Maintenance",
  }[s.state] || "Operational";

  return (
    <div className="status-row">
      <div className="status-row-l">
        <div className="status-row-name">
          <span className="iglyph"><Icon name={s.icon} /></span>
          {s.name}
        </div>
        <div className="status-row-desc">{s.desc}</div>
      </div>
      <div className="status-uptime-meta">
        <div className="label"><span>90-day uptime</span><strong>{s.uptimePct}</strong></div>
        <UptimeBar days={s.uptime} />
      </div>
      <span className={`status-pill is-${s.state}`}>
        <span className="d" />
        {stateLabel}
      </span>
    </div>
  );
}

function UptimeBar({ days }) {
  return (
    <div className="uptime" aria-label="90-day uptime">
      {days.map((d, i) => (
        <span
          key={i}
          className={d === "ok" ? "" : `is-${d}`}
          title={`Day ${90 - i} · ${d === "ok" ? "No incidents" : d}`}
        />
      ))}
    </div>
  );
}

// ──────────────────────────────────────────────────────────────────────
// INCIDENTS
// ──────────────────────────────────────────────────────────────────────
function ActiveIncidents({ incidents }) {
  const active = incidents.filter((i) => i.state !== "resolved");
  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) => <Incident key={i.id} incident={i} />);
}

function Incident({ incident }) {
  return (
    <article className={`incident is-${incident.state}`}>
      <header className="incident-head">
        <h3 className="incident-h">{incident.title}</h3>
        <span className={`status-pill is-${incident.impact}`}>
          <span className="d" />
          {incident.impact === "degraded" ? "Degraded" : incident.impact === "major" ? "Major" : incident.impact === "partial" ? "Partial" : "Maintenance"}
        </span>
      </header>
      <div className="incident-meta">
        <span><strong>Started</strong> {incident.started}</span>
        <span><strong>Duration</strong> {incident.duration}</span>
        <span><strong>Affecting</strong> {incident.affected.join(", ")}</span>
      </div>
      <div className="incident-timeline">
        {incident.updates.map((u, i) => (
          <div key={i} className="incident-update">
            <div>
              <strong>{u.label}</strong>
              <div className="when">{u.time}</div>
            </div>
            <p>{u.body}</p>
          </div>
        ))}
      </div>
    </article>
  );
}

// ──────────────────────────────────────────────────────────────────────
// HISTORY
// ──────────────────────────────────────────────────────────────────────
function History({ days }) {
  return (
    <>
      {days.map((d) => (
        <div key={d.day} className="history-day">
          <div className="history-day-h">{d.day}</div>
          {d.incidents.map((i) => (
            <article key={i.id} className={`incident is-${i.state}`} style={{ marginBottom: 10 }}>
              <header className="incident-head" style={{ marginBottom: 4 }}>
                <h3 className="incident-h" style={{ fontSize: 16 }}>{i.title}</h3>
                <span className={`status-pill is-${i.impact}`}>
                  <span className="d" />
                  {i.impact === "degraded" ? "Degraded" : i.impact === "major" ? "Major" : i.impact === "partial" ? "Partial" : "Maintenance"}
                </span>
              </header>
              <div className="incident-meta" style={{ marginBottom: 0 }}>
                <span><strong>Duration</strong> {i.duration}</span>
                <span><strong>Status</strong> {i.state}</span>
              </div>
            </article>
          ))}
        </div>
      ))}
    </>
  );
}

// ──────────────────────────────────────────────────────────────────────
// SCHEDULED
// ──────────────────────────────────────────────────────────────────────
function Scheduled({ items }) {
  if (items.length === 0) {
    return (
      <div className="incident-empty" style={{ fontSize: 15 }}>
        <em>No scheduled maintenance.</em>
      </div>
    );
  }
  return items.map((s) => (
    <article key={s.id} className="incident is-scheduled">
      <header className="incident-head">
        <h3 className="incident-h">{s.title}</h3>
        <span className="status-pill is-maint"><span className="d" />Scheduled</span>
      </header>
      <div className="incident-meta">
        <span><strong>When</strong> {s.when}</span>
        <span><strong>Duration</strong> {s.duration}</span>
      </div>
      <p style={{ color: "var(--ink-2)", fontSize: 14, lineHeight: 1.55, margin: 0 }}>{s.impact}</p>
    </article>
  ));
}

// ──────────────────────────────────────────────────────────────────────
// SUBSCRIBE
// ──────────────────────────────────────────────────────────────────────
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>
  );
}

// ──────────────────────────────────────────────────────────────────────
// LEGEND
// ──────────────────────────────────────────────────────────────────────
function Legend() {
  const items = [
    ["#5fa86a", "Operational"],
    ["#f5b945", "Degraded"],
    ["#e89554", "Partial outage"],
    ["#c43575", "Major outage"],
    ["#b48dff", "Maintenance"],
  ];
  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>
  );
}

// ──────────────────────────────────────────────────────────────────────
// APP
// ──────────────────────────────────────────────────────────────────────
function StatusPage() {
  // Derive overall state from services + incidents
  const overall = useMemo(() => {
    if (INCIDENTS.some((i) => i.state !== "resolved" && i.impact === "major")) return "major";
    if (INCIDENTS.some((i) => i.state !== "resolved")) return "degraded";
    const states = SERVICES.flatMap((g) => g.services.map((s) => s.state));
    if (states.includes("major")) return "major";
    if (states.includes("degraded") || states.includes("partial")) return "degraded";
    return "ok";
  }, []);

  return (
    <>
      <StatusHero overallState={overall} />

      <section className="status-section">
        <header className="status-section-h">
          <h2>Active <em>incident</em></h2>
          <span className="meta">Live · auto-refreshes</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>
        {SERVICES.map((g) => <ServiceGroup key={g.id} group={g} />)}
        <Legend />
      </section>

      <section className="status-section">
        <header className="status-section-h">
          <h2>Scheduled <em>maintenance</em></h2>
          <span className="meta">Upcoming · EU times</span>
        </header>
        <Scheduled items={SCHEDULED} />
      </section>

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

      <Subscribe />
    </>
  );
}

window.StatusPage = StatusPage;
