'use client';

import { useCallback, useEffect, useMemo, useState } from 'react';

import { RoleGate } from '@/components/auth/RoleGate';
import { IT_OPS_ALLOWED_ROLES } from '@/lib/it-ops-roles';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card';

type DriftShape = {
  collected_at?: string;
  guest_count?: number;
  duplicate_ips?: Record<string, string[]>;
  guest_lan_ips_not_in_declared_sources?: string[];
  declared_lan11_ips_not_on_live_guests?: string[];
  vmid_ip_mismatch_live_vs_all_vmids_doc?: Array<{ vmid: string; live_ip: string; all_vmids_doc_ip: string }>;
  notes?: string[];
};

function hoursSinceIso(iso: string | undefined): number | null {
  if (!iso) return null;
  const t = Date.parse(iso);
  if (Number.isNaN(t)) return null;
  return (Date.now() - t) / (1000 * 60 * 60);
}

export default function ItOpsPage() {
  const [drift, setDrift] = useState<DriftShape | null>(null);
  const [err, setErr] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    setErr(null);
    try {
      const r = await fetch('/api/it/drift', { cache: 'no-store' });
      const j = (await r.json()) as DriftShape & { message?: string };
      if (!r.ok) {
        setErr(j.message || `HTTP ${r.status}`);
        setDrift(null);
        return;
      }
      setDrift(j);
    } catch (e) {
      setErr(e instanceof Error ? e.message : 'Request failed');
      setDrift(null);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    void load();
  }, [load]);

  const staleHours = useMemo(() => hoursSinceIso(drift?.collected_at), [drift?.collected_at]);
  const stale = staleHours !== null && staleHours > 24;

  const onRefresh = async () => {
    setRefreshing(true);
    setErr(null);
    try {
      const r = await fetch('/api/it/refresh', { method: 'POST' });
      const j = (await r.json()) as { message?: string };
      if (!r.ok) {
        setErr(j.message || `Refresh HTTP ${r.status}`);
        setRefreshing(false);
        return;
      }
      await load();
    } catch (e) {
      setErr(e instanceof Error ? e.message : 'Refresh failed');
    } finally {
      setRefreshing(false);
    }
  };

  const dupCount = drift?.duplicate_ips ? Object.keys(drift.duplicate_ips).length : 0;

  return (
    <RoleGate
      allowedRoles={[...IT_OPS_ALLOWED_ROLES]}
      callbackUrl="/it"
      badge="IT Ops"
      title="IT operations"
      subtitle="Sign in with an account that has the sankofa-it-admin realm role (or operator ADMIN for bootstrap)."
    >
      <div className="container mx-auto px-4 py-8">
        <div className="mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
          <div>
            <h1 className="text-3xl font-bold text-white">IT inventory &amp; drift</h1>
            <p className="text-gray-400 text-sm mt-1">
              Data from proxmox read API (Phase 0). Configure{' '}
              <code className="text-gray-300">IT_READ_API_URL</code> on the portal host.
            </p>
          </div>
          <button
            type="button"
            onClick={() => void onRefresh()}
            disabled={refreshing}
            className="inline-flex h-10 items-center justify-center rounded-md bg-orange-600 px-4 text-sm font-medium text-white hover:bg-orange-500 disabled:opacity-50"
          >
            {refreshing ? 'Refreshing…' : 'Refresh inventory'}
          </button>
        </div>

        {err && (
          <div className="mb-6 rounded-lg border border-red-800 bg-red-950/40 px-4 py-3 text-sm text-red-200">
            {err}
          </div>
        )}

        {loading && <p className="text-gray-400">Loading drift…</p>}

        {!loading && drift && (
          <div className="grid gap-6 md:grid-cols-2">
            <Card className="bg-gray-800 border-gray-700">
              <CardHeader>
                <CardTitle className="text-white">Freshness</CardTitle>
              </CardHeader>
              <CardContent className="space-y-2 text-sm text-gray-300">
                <p>
                  <span className="text-gray-500">collected_at:</span>{' '}
                  {drift.collected_at || '—'}
                </p>
                {stale && (
                  <p className="text-amber-400">
                    Snapshot is older than 24h — run export on LAN or use Refresh (requires API key on server).
                  </p>
                )}
                {!stale && staleHours !== null && (
                  <p className="text-green-400">Within 24h window ({Math.round(staleHours)}h ago).</p>
                )}
              </CardContent>
            </Card>

            <Card className="bg-gray-800 border-gray-700">
              <CardHeader>
                <CardTitle className="text-white">Summary</CardTitle>
              </CardHeader>
              <CardContent className="space-y-2 text-sm text-gray-300">
                <p>Guests (live): {drift.guest_count ?? '—'}</p>
                <p>Duplicate guest IPs: {dupCount}</p>
                <p>
                  LAN guests not in declared sources:{' '}
                  {drift.guest_lan_ips_not_in_declared_sources?.length ?? 0}
                </p>
                <p>
                  Declared LAN11 not on live guests:{' '}
                  {drift.declared_lan11_ips_not_on_live_guests?.length ?? 0}
                </p>
                <p>
                  VMID IP mismatch (live vs ALL_VMIDS doc):{' '}
                  {drift.vmid_ip_mismatch_live_vs_all_vmids_doc?.length ?? 0}
                </p>
              </CardContent>
            </Card>

            {dupCount > 0 && (
              <Card className="bg-gray-800 border-red-900 md:col-span-2">
                <CardHeader>
                  <CardTitle className="text-red-400">Duplicate IPs (fix on cluster)</CardTitle>
                </CardHeader>
                <CardContent>
                  <pre className="text-xs text-gray-300 overflow-x-auto">
                    {JSON.stringify(drift.duplicate_ips, null, 2)}
                  </pre>
                </CardContent>
              </Card>
            )}

            {(drift.notes?.length ?? 0) > 0 && (
              <Card className="bg-gray-800 border-gray-700 md:col-span-2">
                <CardHeader>
                  <CardTitle className="text-white">Notes</CardTitle>
                </CardHeader>
                <CardContent>
                  <ul className="list-disc pl-5 text-sm text-gray-300 space-y-1">
                    {drift.notes!.map((n) => (
                      <li key={n}>{n}</li>
                    ))}
                  </ul>
                </CardContent>
              </Card>
            )}
          </div>
        )}
      </div>
    </RoleGate>
  );
}
