'use client';

import { useEffect, useMemo, useState } from 'react';
import { useI18n } from '../../components/I18nProvider';

type HetznerServer = {
  id: number;
  name: string;
  status: string;
  type?: string;
  datacenter?: string;
  publicIp?: string;
  privateIp?: string;
  created?: string;
};

type MonitorResponse = {
  hetzner?: { ok: boolean; error?: string; missingToken?: boolean; servers?: HetznerServer[] };
  k8s?: {
    ok: boolean;
    error?: string;
    nodes?: {
      name: string;
      ready: boolean;
      status: string;
      roles: string[];
      internalIp?: string;
      kubeletVersion?: string;
      osImage?: string;
      lastReadyTransition?: string | null;
    }[];
    pods?: {
      name: string;
      namespace: string;
      phase: string;
      reason?: string | null;
      message?: string | null;
      readyCount: number;
      totalContainers: number;
      restarts: number;
      nodeName?: string;
      hostIP?: string | null;
      podIP?: string | null;
      startedAt?: string | null;
      containers: { name: string; ready: boolean; restartCount: number; state: string; lastState?: string | null }[];
    }[];
  };
  db?: { ok: boolean; error?: string; serverTime?: string; recovery?: boolean; databaseSizeBytes?: number; connections?: { state: string; count: number }[] };
};

const REFRESH_MS = 30000;

function formatBytes(bytes?: number) {
  if (!bytes || Number.isNaN(bytes)) return '—';
  if (bytes < 1024) return `${bytes} B`;
  const kb = bytes / 1024;
  if (kb < 1024) return `${kb.toFixed(1)} KB`;
  const mb = kb / 1024;
  if (mb < 1024) return `${mb.toFixed(1)} MB`;
  const gb = mb / 1024;
  return `${gb.toFixed(2)} GB`;
}

function formatDurationFrom(dateStr?: string | null) {
  if (!dateStr) return '—';
  const started = new Date(dateStr).getTime();
  const diff = Date.now() - started;
  if (Number.isNaN(diff) || diff < 0) return '—';
  const mins = Math.floor(diff / 60000);
  if (mins < 1) return '<1m';
  if (mins < 60) return `${mins}m`;
  const hours = Math.floor(mins / 60);
  if (hours < 24) return `${hours}h`;
  const days = Math.floor(hours / 24);
  return `${days}d`;
}

function statusPill(label: string, ok: boolean) {
  return (
    <span
      style={{
        padding: '2px 8px',
        borderRadius: 999,
        fontSize: 12,
        background: ok ? '#e6f4ea' : '#fdecea',
        color: ok ? '#1b5e20' : '#c62828',
        border: `1px solid ${ok ? '#a5d6a7' : '#f5c6cb'}`,
      }}
    >
      {label}
    </span>
  );
}

export default function MonitorPage() {
  const { t } = useI18n();
  const [data, setData] = useState<MonitorResponse | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [lastUpdated, setLastUpdated] = useState<number | null>(null);

  const hasData = useMemo(() => Boolean(data?.hetzner || data?.k8s || data?.db), [data]);

  async function load() {
    setLoading(true);
    setError(null);
    try {
      const res = await fetch('/api/admin/monitor', { cache: 'no-store' });
      const json = (await res.json()) as MonitorResponse & { error?: string };
      if (!res.ok) {
        setError(json.error || t('monitorLoadFailed'));
        setLoading(false);
        return;
      }
      setData(json);
      setLastUpdated(Date.now());
    } catch (err) {
      setError(t('monitorLoadFailed'));
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => {
    load();
    const id = setInterval(load, REFRESH_MS);
    return () => clearInterval(id);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <main className="panel" style={{ maxWidth: 1100, margin: '40px auto', display: 'grid', gap: 16 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', gap: 12 }}>
        <div>
          <h1>{t('monitorTitle')}</h1>
          <p style={{ margin: 0, color: '#555' }}>{t('monitorLead')}</p>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <button className="button secondary" onClick={load} disabled={loading}>
            {loading ? t('loading') : t('monitorRefresh')}
          </button>
          <span style={{ fontSize: 12, color: '#666' }}>
            {t('monitorLastUpdated')}: {lastUpdated ? new Date(lastUpdated).toLocaleTimeString() : '—'}
          </span>
        </div>
      </div>

      {error ? <p style={{ color: 'red', margin: 0 }}>{error}</p> : null}
      {!hasData && !loading ? <p style={{ margin: 0 }}>{t('monitorNoData')}</p> : null}

      <section style={{ border: '1px solid #eee', borderRadius: 12, padding: 16 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 10 }}>
          <h2 style={{ margin: 0 }}>{t('monitorHetznerTitle')}</h2>
          {data?.hetzner?.ok ? statusPill(t('monitorHealthy'), true) : statusPill(t('monitorAttention'), false)}
        </div>
        {!data?.hetzner ? (
          <p>{t('monitorNoData')}</p>
        ) : data.hetzner.missingToken ? (
          <p style={{ color: '#c77c02' }}>{t('monitorHetznerMissingToken')}</p>
        ) : data.hetzner.ok && (data.hetzner.servers?.length ?? 0) > 0 ? (
          <ul style={{ listStyle: 'none', padding: 0, display: 'grid', gap: 8 }}>
            {data.hetzner.servers!.map((s) => (
              <li key={s.id} style={{ border: '1px solid #eee', borderRadius: 10, padding: 12, display: 'grid', gap: 6 }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                  <div>
                    <strong>{s.name}</strong> — {s.type ?? 'server'} ({s.datacenter ?? 'dc'})
                  </div>
                  {statusPill(s.status, s.status?.toLowerCase() === 'running')}
                </div>
                <div style={{ fontSize: 13, color: '#444', display: 'flex', gap: 12, flexWrap: 'wrap' }}>
                  <span>Public IP: {s.publicIp ?? '—'}</span>
                  <span>Private IP: {s.privateIp ?? '—'}</span>
                  <span>{t('monitorCreated')} {s.created ? new Date(s.created).toLocaleString() : '—'}</span>
                </div>
              </li>
            ))}
          </ul>
        ) : (
          <p style={{ color: 'red' }}>{data.hetzner.error || t('monitorHetznerEmpty')}</p>
        )}
      </section>

      <section style={{ border: '1px solid #eee', borderRadius: 12, padding: 16, display: 'grid', gap: 12 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <h2 style={{ margin: 0 }}>{t('monitorK8sTitle')}</h2>
          {data?.k8s?.ok ? statusPill(t('monitorHealthy'), true) : statusPill(t('monitorAttention'), false)}
        </div>
        {!data?.k8s ? (
          <p>{t('monitorNoData')}</p>
        ) : !data.k8s.ok ? (
          <p style={{ color: 'red', margin: 0 }}>{data.k8s.error ?? t('monitorLoadFailed')}</p>
        ) : (
          <>
            <div>
              <h3 style={{ marginBottom: 6 }}>{t('monitorNodesTitle')}</h3>
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(260px, 1fr))', gap: 10 }}>
                {(data.k8s.nodes ?? []).map((n) => (
                  <div key={n.name} style={{ border: '1px solid #eee', borderRadius: 10, padding: 10 }}>
                    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                      <div>
                        <strong>{n.name}</strong>
                        <div style={{ fontSize: 12, color: '#666' }}>{n.roles.length ? n.roles.join(', ') : 'node'}</div>
                      </div>
                      {statusPill(n.status, n.ready)}
                    </div>
                    <div style={{ fontSize: 13, color: '#444', marginTop: 6 }}>
                      <div>IP: {n.internalIp ?? '—'}</div>
                      <div>{n.kubeletVersion ?? 'kubelet'} · {n.osImage ?? ''}</div>
                      <div style={{ color: '#777' }}>
                        {t('monitorLastReady')}: {n.lastReadyTransition ? new Date(n.lastReadyTransition).toLocaleString() : '—'}
                      </div>
                    </div>
                  </div>
                ))}
              </div>
            </div>

            <div>
              <h3 style={{ marginBottom: 6 }}>{t('monitorPodsTitle')}</h3>
              {(data.k8s.pods ?? []).length === 0 ? (
                <p style={{ margin: 0 }}>{t('monitorNoPods')}</p>
              ) : (
                <div style={{ overflowX: 'auto' }}>
                  <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 14 }}>
                    <thead>
                      <tr>
                        <th style={{ textAlign: 'left', padding: '6px 8px', borderBottom: '1px solid #eee' }}>Namespace</th>
                        <th style={{ textAlign: 'left', padding: '6px 8px', borderBottom: '1px solid #eee' }}>Pod</th>
                        <th style={{ textAlign: 'left', padding: '6px 8px', borderBottom: '1px solid #eee' }}>Ready</th>
                        <th style={{ textAlign: 'left', padding: '6px 8px', borderBottom: '1px solid #eee' }}>{t('monitorRestarts')}</th>
                        <th style={{ textAlign: 'left', padding: '6px 8px', borderBottom: '1px solid #eee' }}>Phase</th>
                        <th style={{ textAlign: 'left', padding: '6px 8px', borderBottom: '1px solid #eee' }}>{t('monitorAge')}</th>
                        <th style={{ textAlign: 'left', padding: '6px 8px', borderBottom: '1px solid #eee' }}>Node</th>
                      </tr>
                    </thead>
                    <tbody>
                      {(data.k8s.pods ?? []).map((p) => (
                        <tr key={`${p.namespace}-${p.name}`}>
                          <td style={{ padding: '6px 8px', borderBottom: '1px solid #f2f2f2' }}>{p.namespace}</td>
                          <td style={{ padding: '6px 8px', borderBottom: '1px solid #f2f2f2' }}>
                            <div style={{ fontWeight: 600 }}>{p.name}</div>
                            <div style={{ fontSize: 12, color: '#666' }}>
                              {p.containers.map((c) => `${c.name} (${c.state}${c.lastState ? `, ${c.lastState}` : ''})`).join('; ')}
                            </div>
                          </td>
                          <td style={{ padding: '6px 8px', borderBottom: '1px solid #f2f2f2' }}>
                            {p.readyCount}/{p.totalContainers}
                          </td>
                          <td style={{ padding: '6px 8px', borderBottom: '1px solid #f2f2f2' }}>{p.restarts}</td>
                          <td style={{ padding: '6px 8px', borderBottom: '1px solid #f2f2f2' }}>
                            {p.phase}
                            {p.reason ? ` (${p.reason})` : ''}
                          </td>
                          <td style={{ padding: '6px 8px', borderBottom: '1px solid #f2f2f2' }}>{formatDurationFrom(p.startedAt)}</td>
                          <td style={{ padding: '6px 8px', borderBottom: '1px solid #f2f2f2' }}>{p.nodeName ?? '—'}</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              )}
            </div>
          </>
        )}
      </section>

      <section style={{ border: '1px solid #eee', borderRadius: 12, padding: 16, display: 'grid', gap: 10 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <h2 style={{ margin: 0 }}>{t('monitorDbTitle')}</h2>
          {data?.db?.ok ? statusPill(t('monitorHealthy'), true) : statusPill(t('monitorAttention'), false)}
        </div>
        {!data?.db ? (
          <p>{t('monitorNoData')}</p>
        ) : !data.db.ok ? (
          <p style={{ color: 'red', margin: 0 }}>{data.db.error ?? t('monitorLoadFailed')}</p>
        ) : (
          <>
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(240px, 1fr))', gap: 8 }}>
              <div style={{ border: '1px solid #eee', borderRadius: 10, padding: 10 }}>
                <div style={{ fontSize: 12, color: '#666' }}>{t('monitorServerTime')}</div>
                <div style={{ fontWeight: 600 }}>{data.db.serverTime ? new Date(data.db.serverTime).toLocaleString() : '—'}</div>
              </div>
              <div style={{ border: '1px solid #eee', borderRadius: 10, padding: 10 }}>
                <div style={{ fontSize: 12, color: '#666' }}>{t('monitorDbSize')}</div>
                <div style={{ fontWeight: 600 }}>{formatBytes(data.db.databaseSizeBytes)}</div>
              </div>
              <div style={{ border: '1px solid #eee', borderRadius: 10, padding: 10 }}>
                <div style={{ fontSize: 12, color: '#666' }}>{t('monitorDbRecovery')}</div>
                <div style={{ fontWeight: 600 }}>{data.db.recovery ? t('yes') : t('no')}</div>
              </div>
            </div>
            <div>
              <h3 style={{ marginBottom: 6 }}>{t('monitorConnections')}</h3>
              {(data.db.connections ?? []).length === 0 ? (
                <p style={{ margin: 0 }}>{t('monitorNoData')}</p>
              ) : (
                <ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', gap: 10, flexWrap: 'wrap' }}>
                  {data.db.connections!.map((c) => (
                    <li key={c.state} style={{ border: '1px solid #eee', borderRadius: 10, padding: '6px 10px' }}>
                      <strong>{c.count}</strong> {c.state}
                    </li>
                  ))}
                </ul>
              )}
            </div>
          </>
        )}
      </section>
    </main>
  );
}
