import { getSubsiteByHost } from '../../utils/subsites.ts';
import {
    checkRateLimit,
    recordRequest,
    getCookieId,
    generateNonce,
    createNonceCookie,
    getClientIp,
} from '../../utils/rateLimit.ts';
import type { APIContext } from 'astro';

interface TMDBResult {
    media_type: string;
    title?: string;
    name?: string;
    release_date?: string;
    first_air_date?: string;
    overview?: string;
    poster_path?: string;
}

interface SearchSuggestion {
    label: string;
    value: string;
    year?: string;
    mediaType: string;
    overview?: string;
    poster_path?: string;
}

export async function GET({ request }: APIContext): Promise<Response> {
    const host = request.headers.get('host');
    const subsite = getSubsiteByHost(host || undefined);

    if (!subsite || subsite.short !== 'req') {
        return new Response('Not found', { status: 404 });
    }

    // Rate limit check (5 requests per second, flood protection at 30/10s)
    const rateCheck = checkRateLimit(request, {
        limit: 5,
        windowMs: 1000,
        burstLimit: 30,
        burstWindowMs: 10_000,
    });

    let cookieId = getCookieId(request);
    const hadCookie = !!cookieId;
    if (!cookieId) {
        cookieId = generateNonce();
    }

    if (!rateCheck.allowed) {
        const errorMsg = rateCheck.isFlooding
            ? { error: 'Too many requests - please slow down' }
            : { error: 'Rate limit exceeded' };
        const response = new Response(JSON.stringify(errorMsg), {
            status: 429,
            headers: {
                'Content-Type': 'application/json',
                'Retry-After': '1',
            },
        });
        if (!hadCookie) {
            response.headers.set('Set-Cookie', createNonceCookie(cookieId));
        }
        console.log(`[search] rate limited: ip=${rateCheck.ip} flooding=${rateCheck.isFlooding}`);
        return response;
    }

    // Record the request for rate limiting
    recordRequest(request, 1000);

    const TMDB_API_KEY = import.meta.env.TMDB_API_KEY;

    if (!TMDB_API_KEY) {
        console.error('TMDB_API_KEY not set');
        const response = new Response(JSON.stringify([]), {
            status: 500,
            headers: { 'Content-Type': 'application/json' },
        });
        if (!hadCookie) {
            response.headers.set('Set-Cookie', createNonceCookie(cookieId));
        }
        return response;
    }

    const url = new URL(request.url);
    const q = url.searchParams.get('q');

    if (!q || typeof q !== 'string' || !q.trim()) {
        const response = new Response(JSON.stringify([]), {
            status: 200,
            headers: { 'Content-Type': 'application/json' },
        });
        if (!hadCookie) {
            response.headers.set('Set-Cookie', createNonceCookie(cookieId));
        }
        return response;
    }

    if (q.length > 100) {
        const response = new Response(JSON.stringify([]), {
            status: 200,
            headers: { 'Content-Type': 'application/json' },
        });
        if (!hadCookie) {
            response.headers.set('Set-Cookie', createNonceCookie(cookieId));
        }
        return response;
    }

    try {
        const apiResponse = await fetch(`https://api.themoviedb.org/3/search/multi?api_key=${TMDB_API_KEY}&query=${encodeURIComponent(q)}`);
        if (!apiResponse.ok) {
            throw new Error(`TMDB API error: ${apiResponse.status}`);
        }
        const data = await apiResponse.json();
        const seen = new Set();
        const filtered = data.results
            .filter(item => {
                if (item.media_type !== 'movie' && item.media_type !== 'tv') return false;
                const key = `${item.media_type}-${item.title || item.name}-${item.release_date?.split('-')[0] || item.first_air_date?.split('-')[0] || ''}`;
                if (seen.has(key)) return false;
                seen.add(key);
                return true;
            })
            .slice(0, 10) // Limit to 10 suggestions
            .map(item => ({
                label: item.title || item.name,
                value: item.title || item.name,
                year: item.release_date?.split('-')[0] || item.first_air_date?.split('-')[0],
                mediaType: item.media_type,
                overview: item.overview,
                poster_path: item.poster_path,
            }));
        const response = new Response(JSON.stringify(filtered), {
            headers: { 'Content-Type': 'application/json' },
        });
        if (!hadCookie) {
            response.headers.set('Set-Cookie', createNonceCookie(cookieId));
        }
        return response;
    } catch (error) {
        console.error('Error fetching suggestions:', error);
        const response = new Response(JSON.stringify([]), {
            status: 500,
            headers: { 'Content-Type': 'application/json' },
        });
        if (!hadCookie) {
            response.headers.set('Set-Cookie', createNonceCookie(cookieId));
        }
        return response;
    }
}