---
import BaseLayout from '../layouts/BaseLayout.astro';
---

<BaseLayout title="Homelab" description="Live status and architecture of my homelab — h0melab.uk">
  <div class="homelab-page">

    <!-- Hero -->
    <div class="page-hero container">
      <div class="accent-line"></div>
      <h1>Homelab <span class="text-accent">Status</span></h1>
      <p class="text-muted font-mono" style="font-size:0.88rem;margin-top:0.5rem">
        h0melab.uk · Edinburgh · 
        <span id="uptime-badge" class="text-accent">fetching uptime…</span>
      </p>
    </div>

    <!-- Architecture diagram -->
    <section class="section container">
      <h2 class="section-title">Architecture</h2>
      <div class="arch-diagram card">
        <div class="arch-grid" id="arch-grid">

          <!-- Tier: Internet -->
          <div class="arch-tier">
            <div class="tier-label font-mono">internet</div>
            <div class="arch-node node-external">
              <span class="node-icon">☁</span>
              <span class="node-name">Cloudflare</span>
              <span class="node-detail font-mono">rcosta.uk · DNS · Email routing</span>
            </div>
          </div>

          <div class="arch-arrow">↓</div>

          <!-- Tier: Edge -->
          <div class="arch-tier">
            <div class="tier-label font-mono">edge</div>
            <div class="arch-node node-router">
              <span class="node-icon">⬡</span>
              <span class="node-name">OPNsense</span>
              <span class="node-detail font-mono">26.1 · GeoIP · WireGuard · Unbound</span>
            </div>
          </div>

          <div class="arch-arrow">↓</div>

          <!-- Tier: Core -->
          <div class="arch-tier">
            <div class="tier-label font-mono">core</div>
            <div class="arch-row">
              <div class="arch-node node-compute">
                <span class="node-icon">▣</span>
                <span class="node-name">Proxmox VE</span>
                <span class="node-detail font-mono">2-node cluster · VLAN trunk</span>
              </div>
              <div class="arch-node node-storage">
                <span class="node-icon">◈</span>
                <span class="node-name">ZFS · zfs-oporto</span>
                <span class="node-detail font-mono">RAIDZ2 · 4×HDD · NFS exports</span>
              </div>
            </div>
          </div>

          <div class="arch-arrow">↓</div>

          <!-- Tier: K8s -->
          <div class="arch-tier">
            <div class="tier-label font-mono">kubernetes</div>
            <div class="arch-row">
              <div class="arch-node node-k8s">
                <span class="node-icon">◎</span>
                <span class="node-name">Control Plane</span>
                <span class="node-detail font-mono">kubeadm · Cilium CNI</span>
              </div>
              <div class="arch-node node-k8s">
                <span class="node-icon">◎</span>
                <span class="node-name">Worker ×2</span>
                <span class="node-detail font-mono">Longhorn · Flux GitOps</span>
              </div>
              <div class="arch-node node-k8s">
                <span class="node-icon">◎</span>
                <span class="node-name">Ingress</span>
                <span class="node-detail font-mono">Traefik · Authelia · cert-manager</span>
              </div>
            </div>
          </div>

          <div class="arch-arrow">↓</div>

          <!-- Tier: Services -->
          <div class="arch-tier">
            <div class="tier-label font-mono">services</div>
            <div class="arch-services">
              {[
                ['Grafana', 'monitoring'],
                ['VictoriaMetrics', 'metrics'],
                ['Netdata', 'telemetry'],
                ['Paperless', 'documents'],
                ['Immich', 'photos'],
                ['Linkwarden', 'bookmarks'],
                ['Jellyfin', 'media'],
                ['Gitea', 'git'],
                ['Authelia', 'SSO'],
                ['Homepage', 'dashboard'],
                ['ntfy', 'notifications'],
                ['Stalwart', 'mail (paused)'],
              ].map(([name, role]) => (
                <div class="service-chip">
                  <span class="chip-name">{name}</span>
                  <span class="chip-role font-mono">{role}</span>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    </section>

    <hr class="glow-divider container" />

    <!-- Live metrics -->
    <section class="section container" id="metrics">
      <h2 class="section-title">Live Metrics</h2>
      <p class="text-muted font-mono" style="font-size:0.8rem;margin-bottom:2rem">
        Auto-refreshes every 30s · 
        <span id="metrics-ts">–</span>
      </p>

      <!-- Summary row -->
      <div class="metrics-summary" id="metrics-summary">
        <!-- JS populated -->
      </div>

      <!-- Per-node detail table -->
      <div class="node-table-wrapper card" style="margin-top:2rem">
        <table class="node-table" id="node-table">
          <thead>
            <tr>
              <th class="font-mono">HOST</th>
              <th class="font-mono">ROLE</th>
              <th class="font-mono">CPU</th>
              <th class="font-mono">RAM</th>
              <th class="font-mono">LOAD</th>
              <th class="font-mono">STATUS</th>
            </tr>
          </thead>
          <tbody id="node-tbody">
            <!-- JS populated -->
          </tbody>
        </table>
      </div>

      <!-- Network I/O -->
      <div style="margin-top:2rem">
        <h3 class="section-title" style="font-size:1.1rem;margin-bottom:1rem">
          Network I/O <span class="text-muted font-mono" style="font-size:0.75rem">(last 5 min average)</span>
        </h3>
        <div class="network-grid" id="network-grid">
          <!-- JS populated -->
        </div>
      </div>
    </section>

    <hr class="glow-divider container" />

    <!-- Domain / service map -->
    <section class="section container">
      <h2 class="section-title">Service Map</h2>
      <p class="text-muted font-mono" style="font-size:0.8rem;margin-bottom:2rem">
        All services live under <span class="text-accent">*.int.h0melab.uk</span> · Authelia SSO on everything external-facing
      </p>
      <div class="service-map-grid">
        {[
          {
            domain: 'auth.h0melab.uk',
            name: 'Authelia',
            desc: 'SSO / 2FA gateway',
            public: true,
          },
          {
            domain: 'grafana.int.h0melab.uk',
            name: 'Grafana',
            desc: 'Dashboards · VictoriaMetrics source',
            public: false,
          },
          {
            domain: 'netdata.int.h0melab.uk',
            name: 'Netdata',
            desc: 'Per-node real-time telemetry',
            public: false,
          },
          {
            domain: 'immich.int.h0melab.uk',
            name: 'Immich',
            desc: 'Photo backup & browse',
            public: false,
          },
          {
            domain: 'paperless.int.h0melab.uk',
            name: 'Paperless-ngx',
            desc: 'Document archive · OIDC auth',
            public: false,
          },
          {
            domain: 'chatai.h0melab.uk',
            name: 'Open WebUI',
            desc: 'Local LLM · Ollama backend',
            public: false,
          },
          {
            domain: 'git.int.h0melab.uk',
            name: 'Gitea',
            desc: 'Internal Git repos',
            public: false,
          },
          {
            domain: 'home.h0melab.uk',
            name: 'Homepage',
            desc: 'Dashboard · FC Porto widget',
            public: false,
          },
        ].map(svc => (
          <div class="card svc-card">
            <div class="svc-header">
              <span class="svc-name font-display">{svc.name}</span>
              {svc.public
                ? <span class="tag" style="color:#FFB800;border-color:#FFB800;background:rgba(255,184,0,0.08)">public</span>
                : <span class="tag">internal</span>
              }
            </div>
            <code class="svc-domain font-mono">{svc.domain}</code>
            <p class="svc-desc text-muted">{svc.desc}</p>
          </div>
        ))}
      </div>
    </section>

  </div>
</BaseLayout>

<script>
// ── Demo / live data (same pattern as HomelabStatus component) ──
const USE_DEMO = true;

const DEMO = {
  nodes: [
    { name: 'pve-01',       role: 'Proxmox',       cpu: 41, ram: 72, load: '3.2',  status: 'online', rx: '1.2 Mb/s', tx: '0.8 Mb/s' },
    { name: 'pve-02',       role: 'Proxmox',       cpu: 28, ram: 65, load: '2.1',  status: 'online', rx: '0.9 Mb/s', tx: '0.4 Mb/s' },
    { name: 'k8s-control',  role: 'K8s control',   cpu: 12, ram: 55, load: '0.9',  status: 'online', rx: '0.3 Mb/s', tx: '0.2 Mb/s' },
    { name: 'k8s-worker1',  role: 'K8s worker',    cpu: 28, ram: 61, load: '2.4',  status: 'online', rx: '2.1 Mb/s', tx: '1.8 Mb/s' },
    { name: 'k8s-worker2',  role: 'K8s worker',    cpu: 19, ram: 58, load: '1.7',  status: 'online', rx: '1.4 Mb/s', tx: '1.1 Mb/s' },
    { name: 'zfs-oporto',   role: 'NAS / ZFS',     cpu:  5, ram: 22, load: '0.3',  status: 'online', rx: '3.2 Mb/s', tx: '4.1 Mb/s' },
    { name: 'opnsense',     role: 'Router',        cpu:  8, ram: 31, load: '0.6',  status: 'online', rx: '8.4 Mb/s', tx: '6.2 Mb/s' },
    { name: 'stalwart-mail',role: 'Mail (paused)', cpu:  0, ram:  0, load: '–',   status: 'offline', rx: '–',        tx: '–'        },
  ],
  summary: { cpu: 20, ram: 58, storage: 61, network: '2.4 Gb/s' },
  uptime: '47d 12h 34m',
};

function bar(pct) {
  if (typeof pct !== 'number') return '<span class="text-muted font-mono" style="font-size:0.75rem">–</span>';
  const c = pct > 85 ? '#FF4444' : pct > 70 ? '#FFB800' : '#00D2BE';
  return `<div style="display:flex;align-items:center;gap:0.5rem">
    <div style="flex:1;height:4px;background:var(--bg-surface);border-radius:2px;overflow:hidden">
      <div style="width:${pct}%;height:100%;background:${c};transition:width 0.8s ease"></div>
    </div>
    <span class="font-mono" style="font-size:0.72rem;color:var(--text-muted);min-width:2.5rem">${pct}%</span>
  </div>`;
}

function statusBadge(s) {
  const c = s === 'online' ? '#00D2BE' : '#FF4444';
  return `<span style="display:inline-flex;align-items:center;gap:0.35rem;font-family:var(--font-mono);font-size:0.72rem;color:${c}">
    <span style="width:6px;height:6px;border-radius:50%;background:${c};box-shadow:0 0 6px ${c}"></span>${s}
  </span>`;
}

async function render() {
  const data = USE_DEMO ? DEMO : DEMO; // swap with real fetch

  // Uptime
  const ut = document.getElementById('uptime-badge');
  if (ut) ut.textContent = `uptime ${data.uptime}`;

  // Timestamp
  const ts = document.getElementById('metrics-ts');
  if (ts) ts.textContent = 'updated ' + new Date().toLocaleTimeString('en-GB', { hour:'2-digit', minute:'2-digit', second:'2-digit' });

  // Summary cards
  const summary = document.getElementById('metrics-summary');
  if (summary) {
    summary.innerHTML = [
      { label: 'Avg CPU',     value: `${data.summary.cpu}%`,        pct: data.summary.cpu },
      { label: 'Avg RAM',     value: `${data.summary.ram}%`,        pct: data.summary.ram },
      { label: 'ZFS Used',    value: `${data.summary.storage}%`,    pct: data.summary.storage },
      { label: 'Network',     value: data.summary.network,          pct: null },
    ].map(m => `
      <div class="card summary-card">
        <div class="summary-label font-mono">${m.label}</div>
        <div class="summary-value font-display">${m.value}</div>
        ${m.pct !== null ? `<div style="margin-top:0.5rem">${bar(m.pct)}</div>` : ''}
      </div>
    `).join('');
  }

  // Node table
  const tbody = document.getElementById('node-tbody');
  if (tbody) {
    tbody.innerHTML = data.nodes.map(n => `
      <tr>
        <td class="font-mono" style="color:var(--text-primary)">${n.name}</td>
        <td class="font-mono text-muted" style="font-size:0.78rem">${n.role}</td>
        <td style="min-width:120px">${bar(n.status === 'offline' ? null : n.cpu)}</td>
        <td style="min-width:120px">${bar(n.status === 'offline' ? null : n.ram)}</td>
        <td class="font-mono text-muted" style="font-size:0.78rem">${n.load}</td>
        <td>${statusBadge(n.status)}</td>
      </tr>
    `).join('');
  }

  // Network I/O
  const netGrid = document.getElementById('network-grid');
  if (netGrid) {
    netGrid.innerHTML = data.nodes
      .filter(n => n.status === 'online')
      .map(n => `
        <div class="card net-card">
          <div class="font-mono" style="font-size:0.75rem;color:var(--petronas-teal);margin-bottom:0.5rem">${n.name}</div>
          <div class="net-row">
            <span class="text-muted font-mono" style="font-size:0.7rem">↓ RX</span>
            <span class="font-mono" style="font-size:0.8rem">${n.rx}</span>
          </div>
          <div class="net-row">
            <span class="text-muted font-mono" style="font-size:0.7rem">↑ TX</span>
            <span class="font-mono" style="font-size:0.8rem">${n.tx}</span>
          </div>
        </div>
    `).join('');
  }
}

render();
setInterval(render, 30_000);
</script>

<style>
  .homelab-page { padding-top: 8rem; }

  .page-hero { margin-bottom: 4rem; }

  .section-title {
    font-family: var(--font-display);
    font-size: 1.4rem;
    margin-bottom: 1.5rem;
  }

  /* Architecture diagram */
  .arch-diagram { padding: 2rem; }

  .arch-grid {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0;
  }

  .arch-tier {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    padding: 1.25rem 0;
    border-bottom: 1px solid var(--border-subtle);
  }
  .arch-tier:last-child { border-bottom: none; }

  .tier-label {
    font-size: 0.65rem;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: 0.25rem;
    align-self: flex-start;
  }

  .arch-row {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
    justify-content: center;
    width: 100%;
  }

  .arch-node {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
    padding: 0.85rem 1.5rem;
    border-radius: 8px;
    border: 1px solid var(--border-subtle);
    background: var(--bg-surface);
    min-width: 180px;
    text-align: center;
    transition: border-color var(--transition-fast);
  }
  .arch-node:hover { border-color: var(--border-glow); }

  .node-icon { font-size: 1.2rem; color: var(--petronas-teal); }
  .node-name { font-family: var(--font-display); font-size: 0.95rem; font-weight: 600; }
  .node-detail { font-size: 0.68rem; color: var(--text-muted); margin-top: 0.1rem; }

  .node-router   .node-icon { color: #FFB800; }
  .node-external .node-icon { color: var(--text-muted); }
  .node-storage  .node-icon { color: #7B9EFF; }

  .arch-arrow {
    font-size: 1.2rem;
    color: var(--petronas-teal);
    opacity: 0.4;
    padding: 0.1rem 0;
  }

  .arch-services {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    justify-content: center;
  }

  .service-chip {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 0.5rem 0.9rem;
    border: 1px solid var(--border-subtle);
    border-radius: 6px;
    background: var(--bg-surface);
    transition: border-color var(--transition-fast);
  }
  .service-chip:hover { border-color: var(--border-glow); }
  .chip-name { font-family: var(--font-display); font-size: 0.82rem; font-weight: 600; }
  .chip-role { font-size: 0.62rem; color: var(--petronas-teal); margin-top: 0.1rem; }

  /* Metrics */
  .metrics-summary {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1rem;
  }

  .summary-card { padding: 1.25rem; }
  .summary-label { font-size: 0.7rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-muted); margin-bottom: 0.4rem; }
  .summary-value { font-size: 1.8rem; font-weight: 700; color: var(--petronas-teal); line-height: 1; }

  /* Node table */
  .node-table-wrapper { overflow-x: auto; padding: 0; }
  .node-table { width: 100%; border-collapse: collapse; }
  .node-table th {
    padding: 0.75rem 1.25rem;
    text-align: left;
    font-size: 0.65rem;
    letter-spacing: 0.12em;
    color: var(--text-muted);
    border-bottom: 1px solid var(--border-subtle);
  }
  .node-table td {
    padding: 0.85rem 1.25rem;
    border-bottom: 1px solid var(--border-subtle);
    vertical-align: middle;
  }
  .node-table tr:last-child td { border-bottom: none; }
  .node-table tr:hover td { background: var(--bg-card-hover); }

  /* Network */
  .network-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 0.75rem;
  }

  .net-card { padding: 1rem; }
  .net-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.3rem; }

  /* Service map */
  .service-map-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 1rem;
  }

  .svc-card { padding: 1.25rem; }
  .svc-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.5rem; }
  .svc-name { font-size: 1rem; }
  .svc-domain { font-size: 0.72rem; color: var(--petronas-teal); display: block; margin-bottom: 0.5rem; }
  .svc-desc { font-size: 0.8rem; }

  @media (max-width: 768px) {
    .metrics-summary { grid-template-columns: 1fr 1fr; }
  }
  @media (max-width: 480px) {
    .metrics-summary { grid-template-columns: 1fr; }
  }
</style>
