import { Injectable, inject } from '@angular/core';
import { SERVER_HEALTH_CHECK_TIMEOUT_MS } from '../constants/server-directory.infrastructure.constants';
import type {
  ServerEndpoint,
  ServerEndpointHealthResult,
  ServerHealthCheckPayload
} from '../../domain/models/server-directory.model';
import { ServerEndpointCompatibilityService } from './server-endpoint-compatibility.service';

@Injectable({ providedIn: 'root' })
export class ServerEndpointHealthService {
  private readonly endpointCompatibility = inject(ServerEndpointCompatibilityService);

  async probeEndpoint(
    endpoint: Pick<ServerEndpoint, 'url'>,
    clientVersion: string | null
  ): Promise<ServerEndpointHealthResult> {
    const startTime = Date.now();

    try {
      const response = await fetch(`${endpoint.url}/api/health`, {
        method: 'GET',
        signal: AbortSignal.timeout(SERVER_HEALTH_CHECK_TIMEOUT_MS)
      });
      const latency = Date.now() - startTime;

      if (response.ok) {
        const payload = await response.json() as ServerHealthCheckPayload;
        const versionCompatibility = this.endpointCompatibility.evaluateServerVersion(
          payload.serverVersion,
          clientVersion
        );
        const serverInstanceId = typeof payload.serverInstanceId === 'string' && payload.serverInstanceId.trim().length > 0
          ? payload.serverInstanceId.trim()
          : undefined;

        if (!versionCompatibility.isCompatible) {
          return {
            status: 'incompatible',
            latency,
            versions: {
              serverInstanceId,
              serverVersion: versionCompatibility.serverVersion,
              clientVersion
            }
          };
        }

        return {
          status: 'online',
          latency,
          versions: {
            serverInstanceId,
            serverVersion: versionCompatibility.serverVersion,
            clientVersion
          }
        };
      }

      return { status: 'offline' };
    } catch {
      try {
        const response = await fetch(`${endpoint.url}/api/servers`, {
          method: 'GET',
          signal: AbortSignal.timeout(SERVER_HEALTH_CHECK_TIMEOUT_MS)
        });
        const latency = Date.now() - startTime;

        if (response.ok) {
          return {
            status: 'online',
            latency
          };
        }
      } catch { /* both checks failed */ }

      return { status: 'offline' };
    }
  }
}
