export interface ServiceTarget {
  name: string;
  url: string;
  path: string;
}

export interface ServiceCheck {
  name: string;
  url: string;
  status: 'healthy' | 'unhealthy' | 'unreachable';
  responseTimeMs: number;
  details?: Record<string, unknown>;
  error?: string;
}

export interface HealthReport {
  overall: 'healthy' | 'degraded' | 'down';
  timestamp: string;
  services: ServiceCheck[];
  summary: { healthy: number; unhealthy: number; unreachable: number; total: number };
}

/**
 * Default service targets (LysnrAI local stack).
 */
export const DEFAULT_SERVICES: ServiceTarget[] = [
  { name: 'Backend API', url: process.env.BACKEND_URL || 'http://localhost:8000', path: '/health' },
  {
    name: 'Platform Service',
    url: process.env.PLATFORM_SERVICE_URL || 'http://localhost:4003',
    path: '/health',
  },
  {
    name: 'Admin Dashboard',
    url: process.env.ADMIN_DASHBOARD_URL || 'http://localhost:3001',
    path: '/api/health',
  },
  {
    name: 'User Dashboard',
    url: process.env.USER_DASHBOARD_URL || 'http://localhost:3002',
    path: '/api/health',
  },
];

export async function checkService(
  svc: ServiceTarget,
  opts?: { timeoutMs?: number }
): Promise<ServiceCheck> {
  const fullUrl = `${svc.url}${svc.path}`;
  const start = performance.now();

  try {
    const res = await fetch(fullUrl, { signal: AbortSignal.timeout(opts?.timeoutMs ?? 5_000) });
    const elapsed = Math.round(performance.now() - start);

    if (res.ok) {
      let details: Record<string, unknown> | undefined;
      try {
        details = (await res.json()) as Record<string, unknown>;
      } catch {
        /* ignore */
      }
      return { name: svc.name, url: svc.url, status: 'healthy', responseTimeMs: elapsed, details };
    }

    return {
      name: svc.name,
      url: svc.url,
      status: 'unhealthy',
      responseTimeMs: elapsed,
      error: `HTTP ${res.status}`,
    };
  } catch (err) {
    const elapsed = Math.round(performance.now() - start);
    return {
      name: svc.name,
      url: svc.url,
      status: 'unreachable',
      responseTimeMs: elapsed,
      error: String(err),
    };
  }
}

export async function generateHealthReport(
  services: ServiceTarget[] = DEFAULT_SERVICES,
  opts?: { timeoutMs?: number }
): Promise<HealthReport> {
  const checks = await Promise.all(services.map(svc => checkService(svc, opts)));

  const healthy = checks.filter(c => c.status === 'healthy').length;
  const unhealthy = checks.filter(c => c.status === 'unhealthy').length;
  const unreachable = checks.filter(c => c.status === 'unreachable').length;

  let overall: HealthReport['overall'] = 'healthy';
  if (unreachable === checks.length) overall = 'down';
  else if (unhealthy > 0 || unreachable > 0) overall = 'degraded';

  return {
    overall,
    timestamp: new Date().toISOString(),
    services: checks,
    summary: { healthy, unhealthy, unreachable, total: checks.length },
  };
}
