import { SearchResult, ContentLinks, VideoLink } from '../../src/types/source.js';

interface FilmMetadata {
    quality?: string;
    size?: string;
    langs?: string[];
}

function parseFilmMetadata(html: string): FilmMetadata {
    const meta: FilmMetadata = {};
    const q = html.match(/Qualit[ée][^:]*:\s*<\/b>\s*([^<\n]+?)\s*<br/i);
    if (q) meta.quality = q[1]!.trim();
    const t = html.match(/Taille[^:]*:\s*<\/b>\s*([^<\n]+?)\s*<br/i);
    if (t) meta.size = t[1]!.trim();
    const l = html.match(/Langue[^:]*:\s*<\/b>\s*([^<\n]+?)\s*<br/i);
    if (l) meta.langs = l[1]!.trim().split(/[,\/]/).map(s => s.trim()).filter(Boolean);
    return meta;
}

/**
 * Extrait les autres versions/qualités disponibles pour le même film.
 * Section "Autres versions disponibles pour ..."
 */
export function parseOtherVersions(html: string, baseUrl: string): { label: string; value: string }[] {
    const out: { label: string; value: string }[] = [];
    const sectionMatch = html.match(/Autres versions disponibles[\s\S]+?<\/div>\s*<\/div>/i);
    if (!sectionMatch) return out;
    const linkRegex = /<a\s+href="([^"]+)"[\s\S]*?🎞️\s*([^<]+?)<\/a>/gi;
    let m: RegExpExecArray | null;
    while ((m = linkRegex.exec(sectionMatch[0])) !== null) {
        const href = absUrl(m[1]!, baseUrl);
        const label = m[2]!.replace(/\s+/g, ' ').trim();
        if (!out.find(o => o.value === href)) out.push({ label, value: href });
    }
    return out;
}


function normalizeTitle(title: string): string {
    return title
        .toLowerCase()
        .normalize('NFD').replace(/[̀-ͯ]/g, '')
        .replace(/\b(web-?dl|web-?rip|blu-?ray|full-?blu-?ray|hdtv|hdrip|dvdrip|bdrip|hdlight|ultra-?hdlight|truefrench|french|multi(?:langues?)?|vff|vfq|vfi|vf|vostfr|english|hdts|cam|ts|r5|dvdscr|x264|x265|h\.?264|h\.?265|hevc)\b/g, '')
        .replace(/\b(720p|1080p|2160p|4k|uhd|3d|sd|hd)\b/g, '')
        .replace(/\(\s*\d{4}\s*\)/g, '')
        .replace(/-\s*saison\s*\d+/gi, '')
        .replace(/[^a-z0-9]/g, '');
}

function deduplicateByTitle<T extends { title: string }>(items: T[]): T[] {
    const seen = new Set<string>();
    return items.filter(it => {
        const k = normalizeTitle(it.title);
        if (!k || seen.has(k)) return false;
        seen.add(k);
        return true;
    });
}

function detectType(href: string): 'movie' | 'series' | 'anime' {
    if (/saison|pack-series|series-(vf|vostfr|terminee)/i.test(href)) return 'series';
    if (/animes?/i.test(href)) return 'anime';
    return 'movie';
}

function absUrl(url: string, baseUrl: string): string {
    let path = url;
    if (url.startsWith('http')) {
        try {
            const u = new URL(url);
            path = u.pathname + u.search + u.hash;
        } catch {
            return url;
        }
    }
    const cleanedBase = baseUrl.replace(/\/$/, '');
    return cleanedBase + '/' + path.replace(/^\//, '');
}

/**
 * Format résultats de recherche : <div class="image-container"><img/></div>
 * puis <div class="content"><div class="titre1"><A href="...">Titre</A></div>
 */
export function parseSearchResults(html: string, baseUrl: string): SearchResult[] {
    const results: SearchResult[] = [];
    const blockRegex = /<div\s+class="image-container">\s*<img[^>]+src="([^"]+)"[^>]*>[\s\S]*?<div\s+class="titre1">\s*<a\s+href="([^"]+)"[^>]*>([\s\S]*?)<\/a>/gi;
    let m: RegExpExecArray | null;
    while ((m = blockRegex.exec(html)) !== null) {
        const image = absUrl(m[1]!, baseUrl);
        const hrefRaw = m[2]!;
        const href = absUrl(hrefRaw, baseUrl);
        const title = m[3]!.replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').trim();
        if (!title) continue;
        let year: string | null = null;
        const yearMatch = title.match(/\(\s*(\d{4})\s*\)/) || hrefRaw.match(/-(\d{4})-/);
        if (yearMatch) {
            year = yearMatch[1];
        }

        results.push({
            title,
            year,
            image,
            hrefPath: href,
            type: detectType(hrefRaw),
            source: 'freetel',
        });
    }
    return deduplicateByTitle(results);
}

/**
 * Format nouveautés (/page/1.html) : <a href="..." data-tip-b64="..."><img alt="Titre" src="..."/></a>
 */
export function parseTrendingResults(html: string, baseUrl: string): SearchResult[] {
    const results: SearchResult[] = [];
    const blockRegex = /<a\s+href="((?:films?-|saison-|pack-series|series-)[^"]+\.html)"[^>]*data-tip-b64="[^"]+"[^>]*>\s*<img\s+alt="([^"]+)"[^>]+src="([^"]+)"/gi;
    let m: RegExpExecArray | null;
    while ((m = blockRegex.exec(html)) !== null) {
        const hrefRaw = m[1]!;
        const title = m[2]!.trim();
        const image = absUrl(m[3]!, baseUrl);
        let year: string | null = null;
        const yearMatch = title.match(/\(\s*(\d{4})\s*\)/) || hrefRaw.match(/-(\d{4})-/);
        if (yearMatch) {
            year = yearMatch[1];
        }

        results.push({
            title,
            year,
            image,
            hrefPath: absUrl(hrefRaw, baseUrl),
            type: detectType(hrefRaw),
            source: 'freetel',
        });
    }
    return deduplicateByTitle(results);
}

/**
 * Parse une fiche (film ou série).
 * - Film  : <input name="lien" value="https://turbobit.net/..."> dans la section #link, précédé d'un <p>HOST</p>
 * - Série : <input name="lien" value="https://liens.free-telecharger.cam/SLUG-episode_N"> (à résoudre via resolveLink)
 */
export function parseContentHTML(html: string, isSeries: boolean): ContentLinks {
    const links: VideoLink[] = [];

    if (isSeries) {
        const episodeRegex = /<input[^>]+name="lien"\s+value="(https?:\/\/liens\.free-telecharger\.[a-z]+\/[^"]+)"/gi;
        let m: RegExpExecArray | null;
        let idx = 0;
        while ((m = episodeRegex.exec(html)) !== null) {
            const url = m[1]!;
            const epMatch = url.match(/episode_(\d+|final|complet)/i);
            const episode = epMatch ? epMatch[1] : null;
            links.push({
                id: url,
                host: 'multi',
                label: episode ? `Épisode ${episode}` : `Lien ${idx + 1}`,
                episode: episode || undefined,
                quality: 'multi',
                url: null,
            });
            idx++;
        }
    } else {
        // Films : section #link contient des blocs (Host name dans <p>, URL dans <input hidden lien>)
        const meta = parseFilmMetadata(html);
        const sectionMatch = html.match(/<div\s+id="link"[\s\S]+/);
        const sec = sectionMatch ? sectionMatch[0] : html;
        const pairRegex = /<p[^>]*>\s*([A-Za-z0-9-]+)\s*<\/p>[\s\S]{0,800}?<input[^>]+name="lien"\s+value="([^"]+)"/gi;
        let m: RegExpExecArray | null;
        while ((m = pairRegex.exec(sec)) !== null) {
            const host = m[1]!.trim();
            const url = m[2]!;
            if (/free-telecharger|trustzone|get-trust-zone/i.test(url)) continue;
            links.push({
                id: url,
                host: host.toLowerCase(),
                label: host,
                quality: meta.quality || 'Inconnu',
                size: meta.size,
                langs: meta.langs,
                url: url,
            });
        }
    }

    return { links };
}

/**
 * Parse la page intermédiaire d'un épisode (liens.free-telecharger.cam/...).
 * Structure : <table class="gridtable"> avec <tr> contenant [HOST] et <a href="URL">.
 */
export function parseEpisodeLinks(html: string): { host: string; url: string }[] {
    const out: { host: string; url: string }[] = [];
    const tableMatch = html.match(/<table[^>]*class="gridtable"[\s\S]*?<\/table>/i);
    if (!tableMatch) return out;
    const rows = tableMatch[0].match(/<tr[\s\S]*?<\/tr>/gi) || [];
    for (const row of rows) {
        const hostMatch = row.match(/\[([^\]]+)\]/);
        const aMatch = row.match(/<a\s+[^>]*href\s*=\s*["']?([^"'\s>]+)/i);
        if (hostMatch && aMatch) {
            out.push({
                host: hostMatch[1]!.toLowerCase().trim(),
                url: aMatch[1]!.trim(),
            });
        }
    }
    return out;
}
