import type { IncomingMessage, ServerResponse } from 'http';
import { readFileSync } from 'fs';
import { join } from 'path';

type VercelRequest = IncomingMessage & {
  query: { [key: string]: string | string[] };
  cookies: { [key: string]: string };
  body: unknown;
};

type VercelResponse = ServerResponse & {
  status: (code: number) => VercelResponse;
  json: (data: unknown) => VercelResponse;
  send: (body: string) => VercelResponse;
};

import { detectBot } from './botDetection/index.js';
import { vercelLogger } from './utils/logger.js';

interface PageData {
  title: string;
  description: string;
  image: string;
  url: string;
  type: string;
}

interface ParkData {
  name: string;
  description?: string;
  banner_image_id?: string;
  banner_image_url?: string;
  location?: {
    city: string;
    country: string;
  };
}

interface RideData {
  name: string;
  description?: string;
  banner_image_id?: string;
  banner_image_url?: string;
  park?: {
    name: string;
  };
}

async function getPageData(pathname: string, fullUrl: string): Promise<PageData> {
  const normalizedPath = pathname.replace(/\/+$/, '') || '/';
  const DEFAULT_FALLBACK_IMAGE = 'https://cdn.thrillwiki.com/images/4af6a0c6-4450-497d-772f-08da62274100/original';
  
  // Individual park page: /parks/{slug}
  if (normalizedPath.startsWith('/parks/') && normalizedPath.split('/').length === 3) {
    const slug = normalizedPath.split('/')[2];
    
    try {
      const response = await fetch(
        `${process.env.SUPABASE_URL}/rest/v1/parks?slug=eq.${slug}&select=name,description,banner_image_id,banner_image_url,location(city,country)`,
        {
          headers: {
            'apikey': process.env.SUPABASE_ANON_KEY!,
            'Authorization': `Bearer ${process.env.SUPABASE_ANON_KEY}`
          }
        }
      );
      
      if (response.ok) {
        const data: unknown = await response.json();
        if (Array.isArray(data) && data.length > 0) {
          const park = data[0] as ParkData;
          const imageUrl = park.banner_image_url || 
            (park.banner_image_id 
              ? `https://cdn.thrillwiki.com/images/${park.banner_image_id}/original`
              : (process.env.DEFAULT_OG_IMAGE || DEFAULT_FALLBACK_IMAGE));
          
          // Match client-side fallback logic
          const description = park.description ?? 
            (park.location 
              ? `${park.name} - A theme park in ${park.location.city}, ${park.location.country}`
              : `${park.name} - A theme park`);
          
          return {
            title: `${park.name} - ThrillWiki`,
            description,
            image: imageUrl,
            url: fullUrl,
            type: 'website'
          };
        }
      }
    } catch (error) {
      vercelLogger.error('Error fetching park data', {
        error: error instanceof Error ? error.message : String(error),
        slug
      });
    }
  }
  
  // Individual ride page: /parks/{park-slug}/rides/{ride-slug}
  if (normalizedPath.match(/^\/parks\/[^/]+\/rides\/[^/]+$/)) {
    const parts = normalizedPath.split('/');
    const rideSlug = parts[4];
    
    try {
      const response = await fetch(
        `${process.env.SUPABASE_URL}/rest/v1/rides?slug=eq.${rideSlug}&select=name,description,banner_image_id,banner_image_url,park(name)`,
        {
          headers: {
            'apikey': process.env.SUPABASE_ANON_KEY!,
            'Authorization': `Bearer ${process.env.SUPABASE_ANON_KEY}`
          }
        }
      );
      
      if (response.ok) {
        const data: unknown = await response.json();
        if (Array.isArray(data) && data.length > 0) {
          const ride = data[0] as RideData;
          const imageUrl = ride.banner_image_url || 
            (ride.banner_image_id 
              ? `https://cdn.thrillwiki.com/images/${ride.banner_image_id}/original`
              : (process.env.DEFAULT_OG_IMAGE || DEFAULT_FALLBACK_IMAGE));
          
          // Match client-side fallback logic
          const description = ride.description || 
            (ride.park?.name
              ? `${ride.name} - A thrilling ride at ${ride.park.name}`
              : `${ride.name} - A thrilling ride`);
          
          return {
            title: `${ride.name} - ThrillWiki`,
            description,
            image: imageUrl,
            url: fullUrl,
            type: 'website'
          };
        }
      }
    } catch (error) {
      vercelLogger.error('Error fetching ride data', {
        error: error instanceof Error ? error.message : String(error),
        slug: rideSlug
      });
    }
  }
  
  // Parks listing
  if (normalizedPath === '/parks' || normalizedPath === '/parks/') {
    return {
      title: 'Theme Parks - ThrillWiki',
      description: 'Browse theme parks and amusement parks from around the world',
      image: process.env.DEFAULT_OG_IMAGE || 'https://cdn.thrillwiki.com/images/4af6a0c6-4450-497d-772f-08da62274100/original',
      url: fullUrl,
      type: 'website'
    };
  }
  
  // Rides listing
  if (normalizedPath === '/rides' || normalizedPath === '/rides/') {
    return {
      title: 'Roller Coasters & Rides - ThrillWiki',
      description: 'Explore roller coasters and theme park rides from around the world',
      image: process.env.DEFAULT_OG_IMAGE || 'https://cdn.thrillwiki.com/images/4af6a0c6-4450-497d-772f-08da62274100/original',
      url: fullUrl,
      type: 'website'
    };
  }
  
  // Default fallback
  return {
    title: 'ThrillWiki - Theme Park & Roller Coaster Database',
    description: 'Explore theme parks and roller coasters worldwide with ThrillWiki',
    image: process.env.DEFAULT_OG_IMAGE || 'https://cdn.thrillwiki.com/images/4af6a0c6-4450-497d-772f-08da62274100/original',
    url: fullUrl,
    type: 'website'
  };
}

function generateOGTags(pageData: PageData): string {
  const { title, description, image, url, type } = pageData;
  
  return `
    <meta property="og:title" content="${escapeHtml(title)}" />
    <meta property="og:description" content="${escapeHtml(description)}" />
    <meta property="og:image" content="${escapeHtml(image)}" />
    <meta property="og:url" content="${escapeHtml(url)}" />
    <meta property="og:type" content="${type}" />
    <meta property="og:site_name" content="ThrillWiki" />
    <meta name="twitter:card" content="summary_large_image" />
    <meta name="twitter:title" content="${escapeHtml(title)}" />
    <meta name="twitter:description" content="${escapeHtml(description)}" />
    <meta name="twitter:image" content="${escapeHtml(image)}" />
    <meta name="twitter:url" content="${escapeHtml(url)}" />
  `.trim();
}

function escapeHtml(text: string): string {
  const map: Record<string, string> = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#39;'
  };
  return text.replace(/[&<>"']/g, m => map[m]);
}

function injectOGTags(html: string, ogTags: string): string {
  // Remove existing OG tags
  html = html.replace(/<meta\s+(?:property|name)="(?:og:|twitter:)[^"]*"[^>]*>/gi, '');
  
  // Inject new tags before </head>
  const headEndIndex = html.indexOf('</head>');
  if (headEndIndex !== -1) {
    return html.slice(0, headEndIndex) + ogTags + '\n' + html.slice(headEndIndex);
  }
  
  return html;
}

export default async function handler(req: VercelRequest, res: VercelResponse): Promise<void> {
  let pathname = '/';
  
  try {
    const userAgent = req.headers['user-agent'] || '';
    const fullUrl = `https://${req.headers.host}${req.url}`;
    pathname = new URL(fullUrl).pathname;
    
    // Comprehensive bot detection with headers
    const botDetection = detectBot(userAgent, req.headers as Record<string, string | string[] | undefined>);
    
    // Enhanced logging with detection details
    if (botDetection.isBot) {
      vercelLogger.info('Bot detected', {
        platform: botDetection.platform || 'unknown',
        confidence: botDetection.confidence,
        score: botDetection.score,
        method: botDetection.detectionMethod,
        path: `${req.method} ${pathname}`,
        userAgent,
        signals: botDetection.metadata.signals.slice(0, 5)
      });
    } else {
      // Log potential false negatives
      if (botDetection.score > 30) {
        vercelLogger.warn('Low confidence bot - not serving SSR', {
          score: botDetection.score,
          path: `${req.method} ${pathname}`,
          userAgent,
          signals: botDetection.metadata.signals
        });
      } else {
        vercelLogger.info('Regular user request', {
          score: botDetection.score,
          path: `${req.method} ${pathname}`
        });
      }
    }
    
    // Read the built index.html
    const htmlPath = join(process.cwd(), 'dist', 'index.html');
    let html = readFileSync(htmlPath, 'utf-8');
    
    if (botDetection.isBot) {
      // Fetch page-specific data
      const pageData = await getPageData(pathname, fullUrl);
      vercelLogger.info('Generated OG tags', {
        title: pageData.title,
        pathname
      });
      
      // Generate and inject OG tags
      const ogTags = generateOGTags(pageData);
      html = injectOGTags(html, ogTags);
      
      res.setHeader('X-Bot-Platform', botDetection.platform || 'unknown');
      res.setHeader('X-Bot-Confidence', botDetection.confidence);
      res.setHeader('X-Bot-Score', botDetection.score.toString());
      res.setHeader('X-Bot-Method', botDetection.detectionMethod);
      res.setHeader('X-SSR-Modified', 'true');
    }
    
    res.setHeader('Content-Type', 'text/html; charset=utf-8');
    res.setHeader('Cache-Control', 'public, max-age=300');
    res.status(200).send(html);
    
  } catch (error) {
    vercelLogger.error('SSR processing failed', {
      error: error instanceof Error ? error.message : String(error),
      pathname
    });
    
    // Fallback: serve original HTML
    try {
      const htmlPath = join(process.cwd(), 'dist', 'index.html');
      const html = readFileSync(htmlPath, 'utf-8');
      res.setHeader('Content-Type', 'text/html; charset=utf-8');
      res.status(200).send(html);
    } catch {
      res.status(500).send('Internal Server Error');
    }
  }
}
