/**
 * Web Worker for pinging CDN resources without blocking the main thread
 * This worker performs fetch requests to check CDN availability
 */

export type CDNPingResult = {
  url: string;
  success: boolean;
  status?: number;
  error?: string;
  timestamp: number;
  responseTime?: number;
};

export type CDNPingMessage =
  | { type: 'PING'; urls: string[] }
  | { type: 'STOP' };

self.addEventListener(
  'message',
  async (event: MessageEvent<CDNPingMessage>) => {
    const { type } = event.data;

    if (type === 'PING') {
      const { urls } = event.data;
      const results: CDNPingResult[] = [];

      // Ping each URL sequentially to avoid overwhelming the network
      for (const url of urls) {
        const startTime = performance.now();
        const timestamp = Date.now();

        try {
          const controller = new AbortController();
          const timeoutId = setTimeout(() => controller.abort(), 10000); // 10s timeout

          // Try CORS mode first to get status codes, fallback to no-cors if needed
          let status: number | undefined;

          try {
            // Try with CORS to get actual status codes
            const response = await fetch(url, {
              method: 'HEAD',
              mode: 'cors',
              signal: controller.signal,
              cache: 'no-store',
            });
            status = response.status;
          } catch {
            // Fallback to no-cors if CORS fails (some CDNs don't allow CORS)
            // In no-cors mode, response is opaque and we can't read status
            await fetch(url, {
              method: 'HEAD',
              mode: 'no-cors',
              signal: controller.signal,
              cache: 'no-store',
            });
            status = undefined; // Can't read status in no-cors mode
          }

          clearTimeout(timeoutId);
          const responseTime = performance.now() - startTime;

          // For reachability testing: 2xx, 3xx, and 403 (Forbidden) are success
          // 403 means the CDN is reachable, just blocking access (which is fine for connectivity test)
          // Other 4xx/5xx are failures
          const success =
            status === undefined ||
            (status >= 200 && status < 400) ||
            status === 403;

          results.push({
            url,
            success,
            status,
            timestamp,
            responseTime: Math.round(responseTime),
          });
        } catch (error) {
          const responseTime = performance.now() - startTime;
          results.push({
            url,
            success: false,
            error: error instanceof Error ? error.message : 'Unknown error',
            timestamp,
            responseTime: Math.round(responseTime),
          });
        }
      }

      self.postMessage({ type: 'PING_RESULT', results });
    } else if (type === 'STOP') {
      self.close();
    }
  },
);
