/**
 * Legacy Redirect Service
 * 
 * This service contains the EXACT same logic as the original index.js
 * to ensure 100% backward compatibility for existing endpoints.
 * 
 * DO NOT MODIFY - This preserves existing behavior exactly.
 */

import axios from 'axios';
import https from 'https';
// import { logger } from '../lib/logger'; // Commented out as not used in legacy service

export interface LegacyRedirectOptions {
  method?: string;
  userAgent?: string;
}

export interface LegacyRedirectResult {
  url: string;
  timestamp: number;
  isSSL: boolean;
  duration?: number;
  statusCode?: number;
  statusText?: string;
  metadata?: any;
  responseBody?: string;
  sslInfo?: any;
  error?: string;
  final?: boolean;
}

/**
 * EXACT replica of the original trackRedirects function from index.js
 * This ensures 100% backward compatibility
 */
export async function trackRedirects(
  url: string,
  redirects: LegacyRedirectResult[] = [],
  options: LegacyRedirectOptions = {}
): Promise<LegacyRedirectResult[]> {
  const startTime = Date.now();
  const currentRedirect: LegacyRedirectResult = { 
    url, 
    timestamp: startTime,
    isSSL: url.toLowerCase().startsWith('https://') 
  };
  
  // Add the current URL to the redirects array
  if (redirects.length === 0) {
    redirects.push(currentRedirect);
  }
  
  try {
    // Prepare request config
    const config = {
      method: options.method || 'GET',
      url: url,
      maxRedirects: 0,
      validateStatus: (status: number) => status >= 200 && status < 600,
      timeout: 15000,
      responseType: 'text' as const,
      decompress: true,
      headers: {} as Record<string, string>
    };
    
    // Add user agent if provided
    if (options.userAgent) {
      config.headers['User-Agent'] = options.userAgent;
    }
    
    // Add HTTPS agent for SSL info
    config.httpsAgent = new https.Agent({
      rejectUnauthorized: false, // Allow self-signed certs for testing
      checkServerIdentity: (host, cert) => {
        // Capture certificate info
        return undefined; // Allow connection
      }
    });
    
    // Make the request
    const response = await axios(config);
    
    // Calculate the duration for this request
    const endTime = Date.now();
    
    // Get response metadata
    const metadata = {
      status: response.status,
      statusText: response.statusText,
      headers: response.headers,
      contentType: response.headers['content-type'],
      contentLength: response.headers['content-length'],
      server: response.headers['server'],
      date: response.headers['date'],
      protocol: response.request?.protocol,
      method: config.method
    };
    
    // Get SSL certificate info if HTTPS
    let sslInfo = null;
    if (url.toLowerCase().startsWith('https://')) {
      try {
        const urlObj = new URL(url);
        const socket = (response.request as any)?.socket;
        
        if (socket && socket.getPeerCertificate) {
          const cert = socket.getPeerCertificate(true);
          sslInfo = {
            valid: socket.authorized,
            issuer: cert.issuer,
            subject: cert.subject,
            validFrom: cert.valid_from,
            validTo: cert.valid_to,
            fingerprint: cert.fingerprint
          };
        }
      } catch (error) {
        sslInfo = { error: 'Failed to retrieve SSL info' };
      }
    }
    
    // Get response body (truncate if too large)
    let responseBody = response.data;
    if (typeof responseBody === 'string' && responseBody.length > 5000) {
      responseBody = responseBody.substring(0, 5000) + '... [truncated]';
    }
    
    // Update the current redirect with all the detailed info
    if (redirects.length > 0 && redirects[redirects.length - 1]!.url === url) {
      redirects[redirects.length - 1]!.duration = endTime - startTime;
      redirects[redirects.length - 1]!.statusCode = response.status;
      redirects[redirects.length - 1]!.statusText = response.statusText;
      redirects[redirects.length - 1]!.metadata = metadata;
      redirects[redirects.length - 1]!.responseBody = responseBody;
      redirects[redirects.length - 1]!.sslInfo = sslInfo;
    } else {
      currentRedirect.duration = endTime - startTime;
      currentRedirect.statusCode = response.status;
      currentRedirect.statusText = response.statusText;
      currentRedirect.metadata = metadata;
      currentRedirect.responseBody = responseBody;
      currentRedirect.sslInfo = sslInfo;
    }
    
    // Check if we have a redirect
    if (response.status >= 300 && response.status < 400 && response.headers.location) {
      // Get the next URL
      let nextUrl = response.headers.location;
      
      // Handle relative URLs
      if (!nextUrl.startsWith('http')) {
        const baseUrl = new URL(url);
        nextUrl = new URL(nextUrl, baseUrl.origin).href;
      }
      
      // Create the next redirect object
      const nextRedirect: LegacyRedirectResult = { 
        url: nextUrl, 
        timestamp: endTime,
        isSSL: nextUrl.toLowerCase().startsWith('https://') 
      };
      
      // Add to redirects array
      redirects.push(nextRedirect);
      
      // Continue following redirects (but always use GET for subsequent requests per HTTP spec)
      const nextOptions = { ...options, method: 'GET' };
      return await trackRedirects(nextUrl, redirects, nextOptions);
    } else {
      // This is the final page
      if (redirects.length > 0 && redirects[redirects.length - 1]!.url === url) {
        redirects[redirects.length - 1]!.final = true;
      } else {
        currentRedirect.final = true;
        redirects.push(currentRedirect);
      }
      return redirects;
    }
  } catch (error: any) {
    // Handle errors
    const endTime = Date.now();
    
    // Update the current redirect with the duration and error info
    if (redirects.length > 0 && redirects[redirects.length - 1]!.url === url) {
      redirects[redirects.length - 1]!.duration = endTime - startTime;
      redirects[redirects.length - 1]!.error = error.message;
      redirects[redirects.length - 1]!.final = true;
      
      // Try to get response info from error object if available
      if (error.response) {
        redirects[redirects.length - 1]!.statusCode = error.response.status;
        redirects[redirects.length - 1]!.statusText = error.response.statusText;
        redirects[redirects.length - 1]!.metadata = {
          status: error.response.status,
          statusText: error.response.statusText,
          headers: error.response.headers,
          method: options.method
        };
      }
    } else {
      currentRedirect.duration = endTime - startTime;
      currentRedirect.error = error.message;
      currentRedirect.final = true;
      
      // Try to get response info from error object if available
      if (error.response) {
        currentRedirect.statusCode = error.response.status;
        currentRedirect.statusText = error.response.statusText;
        currentRedirect.metadata = {
          status: error.response.status,
          statusText: error.response.statusText,
          headers: error.response.headers,
          method: options.method
        };
      }
      
      redirects.push(currentRedirect);
    }
    
    return redirects;
  }
}
