const mangayomiSources = [
    {
        "name": "Comick",
        "langs": ["all", "en", "pt-br", "ru", "fr", "es-419", "pl", "tr", "it", "es", "id", "hu", "vi", "zh-hk", "ar", "de", "zh", "ca", "bg", "th", "fa", "uk", "mn", "ro", "he", "ms", "tl", "ja", "hi", "my", "ko", "cs", "pt", "nl", "sv", "bn", "no", "lt", "el", "sr", "da"],
        "ids": {
            "all": 370890607,
            "en": 955190069,
            "pt-br": 494197461,
            "ru": 1050814052,
            "fr": 380505196,
            "es-419": 296390197,
            "pl": 242913014,
            "tr": 507059585,
            "it": 851891714,
            "es": 115169439,
            "id": 719269008,
            "hu": 719759654,
            "vi": 301477894,
            "zh-hk": 113594984,
            "ar": 602472856,
            "de": 401493183,
            "zh": 752155292,
            "ca": 1069764002,
            "bg": 678531099,
            "th": 311480598,
            "fa": 141560456,
            "uk": 8261465,
            "mn": 565474938,
            "ro": 533803532,
            "he": 459976450,
            "ms": 375702775,
            "tl": 737984097,
            "ja": 796489006,
            "hi": 683471552,
            "my": 778623467,
            "ko": 1065236294,
            "cs": 422767524,
            "pt": 678647945,
            "nl": 698202010,
            "sv": 359879447,
            "bn": 532878423,
            "no": 481504622,
            "lt": 112887841,
            "el": 824905526,
            "sr": 373675453,
            "da": 574420905
        },
        "baseUrl": "https://comick.io",
        "apiUrl": "https://api.comick.fun",
        "iconUrl": "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/icon/all.comick.png",
        "typeSource": "single",
        "itemType": 0,
        "version": "0.1.0",
        "pkgPath": "manga/src/all/comick.js"
    }];

class DefaultExtension extends MProvider {
    constructor() {
        super();
        this.client = new Client();
    }
    getHeaders(url) {
        return {
            "Referer": `${this.source.baseUrl}/`,
            'User-Agent':
                "Tachiyomi Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:110.0) Gecko/20100101 Firefox/110.0"
        };
    }

    async getPopular(page) {
        const url = `${this.source.apiUrl}/v1.0/search?sort=follow&page=${page}&tachiyomi=true`;
        const res = await this.client.get(url, this.getHeaders());
        return this.mangaRes(res.body);
    }

    async getLatestUpdates(page) {
        const url = `${this.source.apiUrl}/v1.0/search?sort=uploaded&page=${page}&tachiyomi=true`;
        const res = await this.client.get(url, this.getHeaders());
        return this.mangaRes(res.body);
    }
    async search(query, page, filterList) {
        let url = `${this.source.apiUrl}/v1.0/search`;

        if (query) {
            url += `?q=${encodeURIComponent(query)}&tachiyomi=true`;
        } else {
            filterList.forEach(filter => {
                if (filter.type === "CompletedFilter" && filter.state) {
                    url += `${this.ll(url)}completed=true`;
                } else if (filter.type === "GenreFilter") {
                    const included = filter.state.filter(e => e.state === 1);
                    const excluded = filter.state.filter(e => e.state === 2);
                    included.forEach(val => url += `${this.ll(url)}genres=${val.value}`);
                    excluded.forEach(val => url += `${this.ll(url)}excludes=${val.value}`);
                } else if (filter.type === "DemographicFilter") {
                    const included = filter.state.filter(e => e.state === 1);
                    included.forEach(val => url += `${this.ll(url)}demographic=${val.value}`);
                } else if (filter.type === "TypeFilter") {
                    const country = filter.state.filter(e => e.state);
                    country.forEach(coun => url += `${this.ll(url)}country=${coun.value}`);
                } else if (filter.type === "SortFilter") {
                    url += `${this.ll(url)}sort=${filter.values[filter.state].value}`;
                } else if (filter.type === "StatusFilter") {
                    url += `${this.ll(url)}status=${filter.values[filter.state].value}`;
                } else if (filter.type === "CreatedAtFilter" && filter.state > 0) {
                    url += `${this.ll(url)}time=${filter.values[filter.state].value}`;
                } else if (filter.type === "MinimumFilter" && filter.state) {
                    url += `${this.ll(url)}minimum=${filter.state}`;
                } else if (filter.type === "FromYearFilter" && filter.state) {
                    url += `${this.ll(url)}from=${filter.state}`;
                } else if (filter.type === "ToYearFilter" && filter.state) {
                    url += `${this.ll(url)}to=${filter.state}`;
                } else if (filter.type === "TagFilter" && filter.state) {
                    const tags = filter.state.split(",");
                    tags.forEach(tag => url += `${this.ll(url)}tags=${tag}`);
                }
            });
            url += `&page=${page}&tachiyomi=true`;
        }
        const res = await this.client.get(url, this.getHeaders());
        return this.mangaRes(res.body);
    }

    async getDetail(url) {
        const apiUrl = `${this.source.apiUrl}${url.replace("#", "")}?tachiyomi=true`;
        const res = await this.client.get(apiUrl, this.getHeaders());
        const data = JSON.parse(res.body);
        const lang = this.source.lang != "all" ? `&lang=${this.source.lang}` : "";
        const chapUrlReq =
            `${this.source.apiUrl}${url.replaceAll("#", '')}chapters?${lang}&tachiyomi=true&page=1`;
        const total = JSON.parse((await this.client.get(chapUrlReq, this.getHeaders())).body).total;
        const newChapUrlReq =
            `${this.source.apiUrl}${url.replaceAll("#", '')}chapters?limit=${parseInt(total, 10)}${lang}&tachiyomi=true&page=1`;
        const newRes = await this.client.get(newChapUrlReq, this.getHeaders());
        const chapters = JSON.parse(newRes.body).chapters.map(chapter => {
            let title = "";
            let scanlator = "";

            if (chapter.chap !== "null" && chapter.vol !== "null") {
                title = this.beautifyChapterName(
                    chapter.vol,
                    chapter.chap,
                    chapter.title
                );
            } else {
                title = chapter.title;
            }

            if (chapter.group_name && chapter.group_name !== "null") {
                scanlator = chapter.group_name
                    .toString()
                    .replace(/]/g, "")
                    .replace(/\[/g, "");
            }

            return {
                name: title,
                url: chapter.hid,
                scanlator: scanlator ?? "",
                dateUpload: new Date(chapter.created_at).valueOf().toString(),
            };
        });

        return {
            author: data.authors?.map(author => author.name).join(', '),
            description: data.comic.desc,
            genres: Array.from(data.comic.md_comic_md_genres.map(g => g.md_genres.name)),
            status: { "1": 0, "2": 1, "3": 3, "4": 2 }[data.comic.status],
            chapters
        };
    }

    async getPageList(url) {
        const apiUrl = `${this.source.apiUrl}/chapter/${url}?tachiyomi=true`;
        const res = await this.client.get(apiUrl, this.getHeaders());
        const data = JSON.parse(res.body);
        return data.chapter.images.map(image => ({
            url: image.url
        }));
    }
    getFilterList() {
        return [
            {
                type_name: "HeaderFilter",
                name: "The filter is ignored when using text search.",
            },
            {
                type_name: "GroupFilter",
                type: "GenreFilter",
                name: "Genre",
                state: [
                    ["4-Koma", "4-koma"],
                    ["Action", "action"],
                    ["Adaptation", "adaptation"],
                    ["Adult", "adult"],
                    ["Adventure", "adventure"],
                    ["Aliens", "aliens"],
                    ["Animals", "animals"],
                    ["Anthology", "anthology"],
                    ["Award Winning", "award-winning"],
                    ["Comedy", "comedy"],
                    ["Cooking", "cooking"],
                    ["Crime", "crime"],
                    ["Crossdressing", "crossdressing"],
                    ["Delinquents", "delinquents"],
                    ["Demons", "demons"],
                    ["Doujinshi", "doujinshi"],
                    ["Drama", "drama"],
                    ["Ecchi", "ecchi"],
                    ["Fan Colored", "fan-colored"],
                    ["Fantasy", "fantasy"],
                    ["Full Color", "full-color"],
                    ["Gender Bender", "gender-bender"],
                    ["Genderswap", "genderswap"],
                    ["Ghosts", "ghosts"],
                    ["Gore", "gore"],
                    ["Gyaru", "gyaru"],
                    ["Harem", "harem"],
                    ["Historical", "historical"],
                    ["Horror", "horror"],
                    ["Incest", "incest"],
                    ["Isekai", "isekai"],
                    ["Loli", "loli"],
                    ["Long Strip", "long-strip"],
                    ["Mafia", "mafia"],
                    ["Magic", "magic"],
                    ["Magical Girls", "magical-girls"],
                    ["Martial Arts", "martial-arts"],
                    ["Mature", "mature"],
                    ["Mecha", "mecha"],
                    ["Medical", "medical"],
                    ["Military", "military"],
                    ["Monster Girls", "monster-girls"],
                    ["Monsters", "monsters"],
                    ["Music", "music"],
                    ["Mystery", "mystery"],
                    ["Ninja", "ninja"],
                    ["Office Workers", "office-workers"],
                    ["Official Colored", "official-colored"],
                    ["Oneshot", "oneshot"],
                    ["Philosophical", "philosophical"],
                    ["Police", "police"],
                    ["Post-Apocalyptic", "post-apocalyptic"],
                    ["Psychological", "psychological"],
                    ["Reincarnation", "reincarnation"],
                    ["Reverse Harem", "reverse-harem"],
                    ["Romance", "romance"],
                    ["Samurai", "samurai"],
                    ["School Life", "school-life"],
                    ["Sci-Fi", "sci-fi"],
                    ["Sexual Violence", "sexual-violence"],
                    ["Shota", "shota"],
                    ["Shoujo Ai", "shoujo-ai"],
                    ["Shounen Ai", "shounen-ai"],
                    ["Slice of Life", "slice-of-life"],
                    ["Smut", "smut"],
                    ["Sports", "sports"],
                    ["Superhero", "superhero"],
                    ["Supernatural", "supernatural"],
                    ["Survival", "survival"],
                    ["Thriller", "thriller"],
                    ["Time Travel", "time-travel"],
                    ["Traditional Games", "traditional-games"],
                    ["Tragedy", "tragedy"],
                    ["User Created", "user-created"],
                    ["Vampires", "vampires"],
                    ["Video Games", "video-games"],
                    ["Villainess", "villainess"],
                    ["Virtual Reality", "virtual-reality"],
                    ["Web Comic", "web-comic"],
                    ["Wuxia", "wuxia"],
                    ["Yaoi", "yaoi"],
                    ["Yuri", "yuri"],
                    ["Zombies", "zombies"]
                ].map(x => ({ type_name: 'TriState', name: x[0], value: x[1] }))
            },
            {
                type_name: "GroupFilter",
                type: "DemographicFilter",
                name: "Demographic",
                state: [
                    ["Shounen", "1"],
                    ["Shoujo", "2"],
                    ["Seinen", "3"],
                    ["Josei", "4"]
                ].map(x => ({ type_name: 'TriState', name: x[0], value: x[1] }))
            },
            {
                type_name: "GroupFilter",
                type: "TypeFilter",
                name: "Type",
                state: [
                    ["Manga", "jp"],
                    ["Manhwa", "kr"],
                    ["Manhua", "cn"]
                ].map(x => ({ type_name: 'CheckBox', name: x[0], value: x[1] }))
            },
            {
                type_name: "SelectFilter",
                type: "SortFilter",
                name: "Sort",
                state: 0,
                values: [
                    ["Most popular", "follow"],
                    ["Most follows", "user_follow_count"],
                    ["Most views", "view"],
                    ["High rating", "rating"],
                    ["Last updated", "uploaded"],
                    ["Newest", "created_at"]
                ].map(x => ({ type_name: 'SelectOption', name: x[0], value: x[1] }))
            },
            {
                type_name: "SelectFilter",
                type: "StatusFilter",
                name: "Status",
                state: 0,
                values: [
                    ["All", "0"],
                    ["Ongoing", "1"],
                    ["Completed", "2"],
                    ["Cancelled", "3"],
                    ["Hiatus", "4"]
                ].map(x => ({ type_name: 'SelectOption', name: x[0], value: x[1] }))
            },
            {
                type_name: 'CheckBox',
                type: "CompletedFilter",
                name: "Completely Scanlated?",
                value: ""
            },
            {
                type_name: "SelectFilter",
                type: "CreatedAtFilter",
                name: "Created at",
                state: 0,
                values: [
                    ["", ""],
                    ["3 days", "3"],
                    ["7 days", "7"],
                    ["30 days", "30"],
                    ["3 months", "90"],
                    ["6 months", "180"],
                    ["1 year", "365"]
                ].map(x => ({ type_name: 'SelectOption', name: x[0], value: x[1] }))
            },
            {
                type_name: "TextFilter",
                type: "MinimumFilter",
                name: "Minimum Chapters",
            },
            {
                type_name: "HeaderFilter",
                name: "From Year, ex: 2010",
            },
            {
                type_name: "TextFilter",
                type: "FromYearFilter",
                name: "From",
            },
            {
                type_name: "HeaderFilter",
                name: "To Year, ex: 2021",
            },
            {
                type_name: "TextFilter",
                type: "ToYearFilter",
                name: "To",
            },
            {
                type_name: "HeaderFilter",
                name: "Separate tags with commas",
            },
            {
                type_name: "TextFilter",
                type: "TagFilter",
                name: "Tags",
            },
        ];
    }
    mangaRes(body) {
        body = JSON.parse(body);
        return {
            list: body.map(manga => ({
                name: manga.title,
                imageUrl: manga.cover_url,
                link: `/comic/${manga.hid}/#`
            })),
            hasNextPage: true
        };
    }
    beautifyChapterName(vol, chap, title) {
        let result = "";

        if (vol && vol.trim() !== "") {
            if (chap && chap.trim() === "") {
                result += `Volume ${vol} `;
            } else {
                result += `Vol. ${vol} `;
            }
        }

        if (chap && chap.trim() !== "") {
            if (vol && vol.trim() === "") {
                result += `Chapter ${chap}`;
            } else {
                result += `Ch. ${chap} `;
            }
        }

        if (title && title.trim() !== "") {
            if (chap && chap.trim() === "") {
                result += title;
            } else {
                result += ` : ${title}`;
            }
        }

        return result;
    }

    ll(url) {
        return url.includes("?") ? "&" : "?";
    }
}
