import { ISource, SearchResult, SelectionData, ContentLinks, MediaType, VideoLink } from '../../src/types/source.js';
import { sourceRegistry } from '../../src/core/registry.js';
import { MovixAPI } from './api.js';
import { CONFIG } from '../../src/utils/config.js';

class MovixSource implements ISource {
    public readonly name = 'movix';
    public readonly displayName = 'Movix';

    public async healthCheck(): Promise<boolean> {
        if (!CONFIG.MOVIX_URL) return false;
        try {
            // A quick check to see if the search endpoint is reachable
            await MovixAPI.search('test');
            return true;
        } catch (e) {
            console.error(`[MOVIX] Health check failed:`, e);
            return false;
        }
    }

    public async search(query: string, mediaType?: MediaType): Promise<SearchResult[]> {
        try {
            const response = await MovixAPI.search(query);
            if (!response || !response.results) return [];

            const results: SearchResult[] = [];
            const searchLower = query.toLowerCase().trim();

            for (const item of response.results) {
                if (!item.name) continue;
                
                // Filtre optionnel pour aligner les résultats avec la recherche
                const nameLower = item.name.toLowerCase();
                const originalLower = item.original_title ? item.original_title.toLowerCase() : '';
                
                // On vérifie si la requête est incluse dans le titre ou le titre original
                if (!nameLower.includes(searchLower) && !originalLower.includes(searchLower)) {
                    // Pour être un peu plus permissif, on vérifie si tous les mots clés y sont
                    const words = searchLower.split(' ');
                    const allWordsMatch = words.every(w => nameLower.includes(w) || originalLower.includes(w));
                    if (!allWordsMatch) continue;
                }

                // Filtrage basique par mediaType si fourni
                if (mediaType) {
                    if (mediaType === 'movie' && item.type !== 'movie') continue;
                    if (mediaType === 'series' && item.type !== 'serie') continue; // Verify if it's 'serie' or 'series'
                }

                const hrefPath = `movix:${item.id}:${item.tmdb_id || 0}:${item.type}`;
                
                let image = null;
                if (item.poster) {
                    image = item.poster.startsWith('http') ? item.poster : `https://image.tmdb.org/t/p/w300/${item.poster}`;
                }

                results.push({
                    title: item.name,
                    year: item.year ? item.year.toString() : null,
                    image,
                    hrefPath,
                    type: item.type === 'movie' ? 'movie' : (item.type === 'serie' || item.type === 'series' ? 'series' : 'other'),
                    source: this.name
                });
            }

            return results;
        } catch (e) {
            console.error(`[MOVIX] Search error:`, e);
            return [];
        }
    }

    public async getTrending(mediaType: MediaType): Promise<SearchResult[]> {
        // Fallback to basic search if trending is not implemented
        return this.search('2024', mediaType);
    }

    public async getContentLinks(identifier: string, season?: number): Promise<ContentLinks> {
        try {
            const parts = identifier.split(':');
            if (parts.length < 4) return { links: [] };

            const [, id, tmdbId, type] = parts;
            const data = await MovixAPI.getDownloadLinks(type, id, tmdbId);
            
            const links: VideoLink[] = [];
            
            if (data && data.data) {
                // Pour chaque host (1fichier, uptobox, etc)
                for (const item of data.data) {
                    if (!item.links || !Array.isArray(item.links)) continue;
                    
                    const host = item.host || 'unknown';
                    const quality = item.qualite || 'Unknown';
                    const lang = item.langue || 'Unknown';
                    const size = item.size || '';
                    
                    for (const linkObj of item.links) {
                        const linkId = linkObj.id;
                        if (!linkId) continue;

                        links.push({
                            id: `${linkId}|${id}`, // Store both linkId and titleId
                            host: host,
                            label: `${quality} - ${lang}`,
                            url: null, // Resolves later
                            size: size,
                            quality: quality,
                            langs: [lang]
                        });
                    }
                }
            }

            return { links };
        } catch (e) {
            console.error(`[MOVIX] Error in getContentLinks:`, e);
            return { links: [] };
        }
    }

    public async getSelection(identifier: string, type?: string, seasonValue?: string | number): Promise<SelectionData> {
        const content = await this.getContentLinks(identifier);
        return {
            links: content.links,
            seasons: [],
            isSeries: type === 'series'
        };
    }

    public async resolveLink(combinedId: string): Promise<string | null> {
        try {
            const [linkId, titleId] = combinedId.split('|');
            if (!linkId || !titleId) return null;

            const res = await MovixAPI.decodeLink(linkId, titleId);
            if (res && res.url) {
                return res.url;
            }
            return null;
        } catch (e) {
            console.error(`[MOVIX] ResolveLink error for ${combinedId}:`, e);
            return null;
        }
    }
}

sourceRegistry.register(new MovixSource());
