// Settings start
const preferedQualityOption = "Auto"; // ["Auto", "2160p", "1080p", "720p", "480p"]
const debridService = "realdebrid"; // ["realdebrid", "alldebrid", "premiumize", "torbox", "debridlink"]
const debridApiKey = "";
const allowAdultContent = true; // [true, false]
// Settings end

async function searchResults(keyword) {
    try {
        const moviesresponse = await fetchv2(
            "https://v3-cinemeta.strem.io/catalog/movie/top/search=" + encodeURIComponent(keyword) + ".json"
        );
        const moviesdata = await moviesresponse.json();

        const results = moviesdata.metas.map(item => ({
            title: item.name.trim(),
            image: item.poster.trim(),
            href: "Movie: " + (item.id.startsWith("tt") ? item.id : "")
        }));

        const showsresponse = await fetchv2(
            "https://v3-cinemeta.strem.io/catalog/series/top/search=" + encodeURIComponent(keyword) + ".json"
        );
        const showsdata = await showsresponse.json();

        const showResults = showsdata.metas.map(item => ({
            title: item.name.trim(),
            image: item.poster.trim(),
            href: "TV: " + (item.id.startsWith("tt") ? item.id : "")
        }));

        results.push(...showResults);

        return JSON.stringify(results);
    } catch (err) {
        return JSON.stringify([{
            title: "Error",
            image: "Error",
            href: "Error"
        }]);
    }
}

async function extractDetails(ID) {
    try {
        let decodedID = decodeURIComponent(ID);
        let actualID = decodedID;
        let type = "movie";

        if (decodedID.startsWith("Movie: ")) {
            actualID = decodedID.replace("Movie: ", "");
            type = "movie";
        } else if (decodedID.startsWith("TV: ")) {
            actualID = decodedID.replace("TV: ", "");
            type = "series";
        }

        const url = "https://v3-cinemeta.strem.io/meta/" + type + "/" + actualID + ".json";
        const response = await fetchv2(url);
        const data = await response.json();

        return JSON.stringify([{
            description: data.meta.description || "N/A",
            aliases: "N/A",
            airdate: data.meta.released || "N/A"
        }]);
    } catch (err) {
        return JSON.stringify([{
            description: "Error",
            aliases: "Error",
            airdate: "Error"
        }]);
    }
}

async function extractEpisodes(ID) {
    let decodedID = decodeURIComponent(ID);
    let actualID = decodedID;
    let type = "movie";

    if (decodedID.startsWith("Movie: ")) {
        actualID = decodedID.replace("Movie: ", "");
        type = "movie";
    } else if (decodedID.startsWith("TV: ")) {
        actualID = decodedID.replace("TV: ", "");
        type = "series";
    }

    const results = [];

    try {
        if (type === "series") {
            const response = await fetchv2("https://v3-cinemeta.strem.io/meta/series/" + actualID + ".json");
            const data = await response.json();
            
            const videos = data.meta.videos || [];
            
            const shouldAdjust = videos.length > 0 && videos[0].season === 0;
            
            let currentSeason = 0;
            let episodeCounter = 0;
            
            for (const video of videos) {
                const adjustedSeason = shouldAdjust ? video.season + 1 : video.season;
                if (adjustedSeason !== currentSeason) {
                    currentSeason = adjustedSeason;
                    episodeCounter = 0;
                }
                
                episodeCounter++;
                
                let adjustedId = video.id || "";
                if (adjustedId && shouldAdjust) {
                    const idParts = adjustedId.split(':');
                    if (idParts.length === 3) {
                        idParts[1] = String(adjustedSeason);
                        adjustedId = idParts.join(':');
                    }
                }
                
                results.push({
                    href: "TV: " + adjustedId,
                    number: episodeCounter
                });
            }

            return JSON.stringify(results);
        } else if (type === "movie") {
            return JSON.stringify([{
                href: "Movie: " + (actualID || ""),
                number: 1
            }]);
        }
    } catch (err) {
        return JSON.stringify([{
            href: "Error",
            number: "Error"
        }]);
    }
}

async function extractStreamUrl(ID) {
    let decodedID = decodeURIComponent(ID);
    let actualID = decodedID;
    let type = "movie";

    if (decodedID.startsWith("Movie: ")) {
        actualID = decodedID.replace("Movie: ", "");
        type = "movie";
    } else if (decodedID.startsWith("TV: ")) {
        actualID = decodedID.replace("TV: ", "");
        type = "series";
    }

    try {
        const userConfig = {
            streaming_provider: {
                service: debridService,
                token: debridApiKey
            }
        };
        
        if (allowAdultContent) {
            userConfig.nudity_filter = ["Disable"];
            userConfig.certification_filter = ["Disable"];
        } else {
            userConfig.nudity_filter = ["Severe", "Moderate"];
            userConfig.certification_filter = ["Adults+"];
        }
        
        const url = await encrypt({
            customUserData: userConfig
        });

        const match = url.match(/\/([^\/]+)\/manifest\.json$/);
        const encryptedConfig = match ? match[1] : null;

        if (!encryptedConfig) {
            return JSON.stringify({
                streams: [],
                subtitle: "https://none.com"
            });
        }

        const endpoint = type === "movie" 
            ? "https://mediafusion.elfhosted.com/" + encryptedConfig + "/stream/movie/" + actualID + ".json"
            : "https://mediafusion.elfhosted.com/" + encryptedConfig + "/stream/series/" + actualID + ".json";
            
        const response = await fetchv2(endpoint);
        const data = await response.json();
        
        if (!data.streams || !Array.isArray(data.streams)) {
            return JSON.stringify({
                streams: [],
                subtitle: "https://none.com"
            });
        }
        
        const streamsByQuality = {
            "2160p": [],
            "1080p": [],
            "720p": [],
            "480p": []
        };
        
        for (const stream of data.streams) {
            const name = stream.name || "";
            let quality = null;
            
            if (name.includes("2160P")) {
                quality = "2160p";
            } else if (name.includes("1080P")) {
                quality = "1080p";
            } else if (name.includes("720P")) {
                quality = "720p";
            } else if (name.includes("480P")) {
                quality = "480p";
            }
            
            if (quality && streamsByQuality[quality]) {
                streamsByQuality[quality].push({
                    title: (stream.name || "Unknown").replace(/\n/g, " "),
                    streamUrl: stream.url || "",
                    headers: {}
                });
            }
        }
        
        let results = [];
        
        if (preferedQualityOption === "Auto") {
            results.push(...streamsByQuality["2160p"].slice(0, 5));
            results.push(...streamsByQuality["1080p"].slice(0, 5));
            results.push(...streamsByQuality["720p"].slice(0, 5));
            results.push(...streamsByQuality["480p"].slice(0, 5));
        } else {
            if (streamsByQuality[preferedQualityOption]) {
                results = streamsByQuality[preferedQualityOption].slice(0, 10);
            }
        }
        
        return JSON.stringify({
            streams: results,
            subtitle: "https://none.com"
        });
    } catch (err) {
        return JSON.stringify({
            streams: [],
            subtitle: "https://none.com"
        });
    }
}

async function encrypt(config = {}) {
    const baseUrl = config.baseUrl || 'https://mediafusion.elfhosted.com';
    
    try {
        let userData;
        
        if (config.customUserData) {
            userData = config.customUserData;
        } else {
            userData = {};
            
            if (config.provider && config.token) {
                userData.streaming_provider = {
                    service: config.provider,
                    token: config.token
                };
                
                if (config.username) {
                    userData.streaming_provider.username = config.username;
                }
            }
            
            if (config.catalogs && config.catalogs.length > 0) {
                userData.selected_catalogs = config.catalogs;
            }
            
            if (config.enableCatalogs !== undefined) {
                userData.enable_catalogs = config.enableCatalogs;
            } else {
                userData.enable_catalogs = true;
            }
            
            if (config.maxSizeGB !== undefined && config.maxSizeGB > 0) {
                userData.max_size = config.maxSizeGB * 1024 * 1024 * 1024; 
            }
            
            if (config.maxStreamsPerResolution !== undefined) {
                userData.max_streams_per_resolution = config.maxStreamsPerResolution;
            } else {
                userData.max_streams_per_resolution = 10;
            }
            
            if (config.sortingPriority) {
                userData.torrent_sorting_priority = config.sortingPriority;
            } else {
                userData.torrent_sorting_priority = ["cached", "resolution", "size_mb"];
            }
            
            if (config.showFullTorrentName !== undefined) {
                userData.show_full_torrent_name = config.showFullTorrentName;
            } else {
                userData.show_full_torrent_name = true;
            }
            
            if (config.nudityFilter) {
                userData.nudity_filter = config.nudityFilter;
            } else {
                userData.nudity_filter = ["Disable"];
            }
            
            if (config.certificationFilter) {
                userData.certification_filter = config.certificationFilter;

            } else {
                userData.certification_filter = ["Disable"];
            }
            
            if (config.qualityFilter) {
                userData.quality_filter = config.qualityFilter;
            } else {
                userData.quality_filter = [];
            }
            
            if (config.apiPassword) {
                userData.api_password = config.apiPassword;
            }
            
            if (config.mediaflowConfig) {
                userData.mediaflow_config = config.mediaflowConfig;
            }
            
            if (config.rpdbConfig) {
                userData.rpdb_config = config.rpdbConfig;
            }
        }
        
        const response = await fetchv2(
            `${baseUrl}/encrypt-user-data`, 
            { 'Content-Type': 'application/json' }, 
            "POST", 
            JSON.stringify(userData)
        );
        
        const data = await response.json();

        
        const installationUrl = `${baseUrl}/${data.encrypted_str}/manifest.json`;
        return installationUrl;
        
    } catch (error) {
        console.error('Error generating MediaFusion URL:'+ error);
        throw error;
    }
}