import * as React from 'react';

/** Shape of the /health API response. */
interface HealthResponse {
  status: 'ok' | 'degraded';
  version?: string;
  uptime?: number;
  services: {
    postgres: 'connected' | 'disconnected';
    redis: 'connected' | 'disconnected';
  };
}

type ServiceStatus = 'connected' | 'disconnected' | 'unknown';

interface HealthState {
  postgres: ServiceStatus;
  redis: ServiceStatus;
  version: string | null;
  uptime: number | null;
  lastChecked: Date | null;
  reachable: boolean;
}

const initialState: HealthState = {
  postgres: 'unknown',
  redis: 'unknown',
  version: null,
  uptime: null,
  lastChecked: null,
  reachable: true,
};

/** Formats seconds into a human-readable uptime string. */
function formatUptime(seconds: number): string {
  const days = Math.floor(seconds / 86400);
  const hours = Math.floor((seconds % 86400) / 3600);
  const minutes = Math.floor((seconds % 3600) / 60);
  const parts: string[] = [];
  if (days > 0) parts.push(`${days}d`);
  if (hours > 0) parts.push(`${hours}h`);
  parts.push(`${minutes}m`);
  return parts.join(' ');
}

interface StatusCardProps {
  label: string;
  status: ServiceStatus;
}

/** Card displaying the connectivity status of a single service. */
function StatusCard({ label, status }: StatusCardProps): React.JSX.Element {
  const isConnected = status === 'connected';
  const isUnknown = status === 'unknown';

  return (
    <div className={`rounded-xl border p-6 shadow-sm ${
      isUnknown
        ? 'border-slate-200 bg-slate-50'
        : isConnected
        ? 'border-green-200 bg-green-50'
        : 'border-red-200 bg-red-50'
    }`}>
      <p className="text-sm font-medium text-slate-600">{label}</p>
      <div className="mt-2 flex items-center gap-2">
        <span className={`inline-block h-3 w-3 rounded-full ${
          isUnknown ? 'bg-slate-400' : isConnected ? 'bg-green-500' : 'bg-red-500'
        }`} />
        <span className={`text-lg font-semibold ${
          isUnknown ? 'text-slate-600' : isConnected ? 'text-green-700' : 'text-red-700'
        }`}>
          {isUnknown ? 'Checking…' : isConnected ? 'Connected' : 'Disconnected'}
        </span>
      </div>
    </div>
  );
}

/**
 * Health page — shows PostgreSQL and Redis connectivity status.
 * Polls GET /health every 30 seconds. No authentication required.
 * Route: /dashboard/health
 */
export default function Health(): React.JSX.Element {
  const [health, setHealth] = React.useState<HealthState>(initialState);
  const [loading, setLoading] = React.useState<boolean>(true);

  const checkHealth = React.useCallback(async (): Promise<void> => {
    try {
      const response = await fetch('/health');
      const data = (await response.json()) as HealthResponse;

      setHealth({
        postgres: data.services?.postgres ?? 'unknown',
        redis: data.services?.redis ?? 'unknown',
        version: data.version ?? null,
        uptime: data.uptime ?? null,
        lastChecked: new Date(),
        reachable: true,
      });
    } catch {
      setHealth((prev) => ({
        ...prev,
        postgres: 'disconnected',
        redis: 'disconnected',
        lastChecked: new Date(),
        reachable: false,
      }));
    } finally {
      setLoading(false);
    }
  }, []);

  React.useEffect(() => {
    void checkHealth();
    const interval = setInterval(() => { void checkHealth(); }, 30_000);
    return () => { clearInterval(interval); };
  }, [checkHealth]);

  return (
    <div>
      <div className="mb-6 flex items-center justify-between">
        <h1 className="text-2xl font-bold text-slate-900">System Health</h1>
        <button
          onClick={() => { void checkHealth(); }}
          disabled={loading}
          className="rounded-md border border-slate-300 px-3 py-1.5 text-sm hover:bg-slate-50 disabled:opacity-40"
        >
          Refresh
        </button>
      </div>

      {!health.reachable && (
        <div className="mb-6 rounded-md bg-red-50 px-4 py-3 text-sm text-red-700" role="alert">
          API is unreachable. Check that the server is running.
        </div>
      )}

      <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
        <StatusCard label="PostgreSQL" status={loading ? 'unknown' : health.postgres} />
        <StatusCard label="Redis" status={loading ? 'unknown' : health.redis} />
      </div>

      {/* Metadata */}
      {(health.version !== null || health.uptime !== null) && (
        <div className="mt-6 rounded-xl border border-slate-200 bg-white p-6 shadow-sm">
          <h2 className="mb-4 text-base font-semibold text-slate-900">API Details</h2>
          <dl className="space-y-2">
            {health.version !== null && (
              <div className="flex gap-4">
                <dt className="w-24 text-sm font-medium text-slate-500">Version</dt>
                <dd className="text-sm text-slate-900">{health.version}</dd>
              </div>
            )}
            {health.uptime !== null && (
              <div className="flex gap-4">
                <dt className="w-24 text-sm font-medium text-slate-500">Uptime</dt>
                <dd className="text-sm text-slate-900">{formatUptime(health.uptime)}</dd>
              </div>
            )}
          </dl>
        </div>
      )}

      {/* Last checked */}
      {health.lastChecked !== null && (
        <p className="mt-4 text-xs text-slate-400">
          Last checked: {health.lastChecked.toLocaleTimeString()} — auto-refreshes every 30 seconds
        </p>
      )}
    </div>
  );
}
