// http://localhost:5757/api/番薯动漫[漫]?ac=list&t=1&pg=1
// http://localhost:5757/api/番薯动漫[漫]?ac=detail&ids=/voddetail/USJJJJJk.html
// http://localhost:5757/api/番薯动漫[漫]?wd=我的&pg=1
// http://localhost:5757/api/番薯动漫[漫]?play=/vodplay/USJJJJJk-2-1.html&flag=由qq倾情打造
const { getHtml } = $.require('./_lib.request.js')


const UA = randomUa.generateUa(1, {
    device: ['pc'],            // 设备类型为PC
    pcOs: ['windows'],         // 操作系统为Windows
    windowsApp: ['edge']       // 浏览器应用为Edge
});

var rule = {
    类型: '影视',
    title: '番薯动漫',
    desc: '番薯动漫纯js版本',
    host: 'https://www.fsdm02.com',
    homeUrl: '',
    url: '',
    searchUrl: '/vodsearch/-------------.html?wd=**',
    searchable: 2,
    quickSearch: 0,
    timeout: 3000,
    play_parse: true,
    filterable: 1,
    headers: {
        // 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0',
        'User-Agent': UA,
        'Referer': 'https://www.fsdm02.com',
        'cookie': ''
    },
    class_parse: async () => {
        return {
            class: [
                {
                    "type_id": "1",
                    "type_name": "TV番剧"
                },
                {
                    "type_id": "3",
                    "type_name": "剧场版"
                },
                {
                    "type_id": "20",
                    "type_name": "4k分区"
                },
                {
                    "type_id": "21",
                    "type_name": "欧美动漫"
                }
            ],
            filters: {
                "1": [
                    {
                        "name": "年份",
                        "key": "year",
                        "value": [
                            {
                                "n": "全部",
                                "v": ""
                            },
                            {
                                "n": "2024",
                                "v": "2024"
                            },
                            {
                                "n": "2023",
                                "v": "2023"
                            },
                            {
                                "n": "2022",
                                "v": "2022"
                            },
                            {
                                "n": "2021",
                                "v": "2021"
                            },
                            {
                                "n": "2020",
                                "v": "2020"
                            },
                            {
                                "n": "2019",
                                "v": "2019"
                            },
                            {
                                "n": "2018",
                                "v": "2018"
                            },
                            {
                                "n": "2017",
                                "v": "2017"
                            },
                            {
                                "n": "2016",
                                "v": "2016"
                            },
                            {
                                "n": "2015",
                                "v": "2015"
                            },
                            {
                                "n": "2014",
                                "v": "2014"
                            },
                            {
                                "n": "2013",
                                "v": "2013"
                            },
                            {
                                "n": "2012",
                                "v": "2012"
                            },
                            {
                                "n": "2011",
                                "v": "2011"
                            },
                            {
                                "n": "2010",
                                "v": "2010"
                            },
                            {
                                "n": "2009",
                                "v": "2009"
                            },
                            {
                                "n": "2008",
                                "v": "2008"
                            },
                            {
                                "n": "2007",
                                "v": "2007"
                            },
                            {
                                "n": "2006",
                                "v": "2006"
                            },
                            {
                                "n": "2005",
                                "v": "2005"
                            },
                            {
                                "n": "2004",
                                "v": "2004"
                            },
                            {
                                "n": "2003",
                                "v": "2003"
                            },
                            {
                                "n": "2002",
                                "v": "2002"
                            },
                            {
                                "n": "2001",
                                "v": "2001"
                            },
                            {
                                "n": "2000",
                                "v": "2000"
                            }
                        ],
                        "init": ""
                    },
                    {
                        "name": "排序",
                        "key": "order",
                        "value": [
                            {
                                "n": "时间排序",
                                "v": "time"
                            },
                            {
                                "n": "人气排序",
                                "v": "hits"
                            },
                            {
                                "n": "评分排序",
                                "v": "score"
                            }
                        ]
                    }
                ],
                "3": [
                    {
                        "name": "地区",
                        "key": "area",
                        "value": [
                            {
                                "n": "全部",
                                "v": ""
                            },
                            {
                                "n": "日本",
                                "v": "%E6%97%A5%E6%9C%AC"
                            }
                        ],
                        "init": ""
                    },
                    {
                        "name": "年份",
                        "key": "year",
                        "value": [
                            {
                                "n": "全部",
                                "v": ""
                            },
                            {
                                "n": "2024",
                                "v": "2024"
                            },
                            {
                                "n": "2023",
                                "v": "2023"
                            },
                            {
                                "n": "2022",
                                "v": "2022"
                            },
                            {
                                "n": "2021",
                                "v": "2021"
                            },
                            {
                                "n": "2020",
                                "v": "2020"
                            },
                            {
                                "n": "2019",
                                "v": "2019"
                            },
                            {
                                "n": "2018",
                                "v": "2018"
                            },
                            {
                                "n": "2017",
                                "v": "2017"
                            },
                            {
                                "n": "2016",
                                "v": "2016"
                            },
                            {
                                "n": "2015",
                                "v": "2015"
                            },
                            {
                                "n": "2014",
                                "v": "2014"
                            },
                            {
                                "n": "2013",
                                "v": "2013"
                            },
                            {
                                "n": "2012",
                                "v": "2012"
                            },
                            {
                                "n": "2011",
                                "v": "2011"
                            },
                            {
                                "n": "2010",
                                "v": "2010"
                            },
                            {
                                "n": "2009",
                                "v": "2009"
                            },
                            {
                                "n": "2008",
                                "v": "2008"
                            },
                            {
                                "n": "2007",
                                "v": "2007"
                            },
                            {
                                "n": "2006",
                                "v": "2006"
                            },
                            {
                                "n": "2005",
                                "v": "2005"
                            },
                            {
                                "n": "2004",
                                "v": "2004"
                            },
                            {
                                "n": "2003",
                                "v": "2003"
                            },
                            {
                                "n": "2002",
                                "v": "2002"
                            },
                            {
                                "n": "2001",
                                "v": "2001"
                            },
                            {
                                "n": "2000",
                                "v": "2000"
                            }
                        ],
                        "init": ""
                    },
                    {
                        "name": "排序",
                        "key": "order",
                        "value": [
                            {
                                "n": "时间排序",
                                "v": "time"
                            },
                            {
                                "n": "人气排序",
                                "v": "hits"
                            },
                            {
                                "n": "评分排序",
                                "v": "score"
                            }
                        ]
                    }
                ],
            }
        }
    },
    预处理: async () => {
        return []
    },
    推荐: async () => {
        return []
    },
    一级: async function (tid, pg, filter, extend) {
        let { MY_CATE, input } = this;
        let html;
        if (extend.class === "20" || extend.class === "21") {
            html = (await _req(`${rule.host}/vodshow/${tid}--------${pg}---.html`)).content;
        } else {
            // https://www.fsdm02.com/vodshow/1--------2---2022.html
            // https://www.fsdm02.com/vodshow/3--hits---------2023.html                        
            html = (await _req(`${rule.host}/vodshow/${tid}-${extend.area || ""}-${extend.order || ""}------${pg}---${extend.year || ""}.html`)).content;
        }
        const $ = pq(html);
        let videos = [];
        for (const item of $(".module>a")) {
            const img = $(item).find("img:first")[0],
                a = item,
                hdinfo = $($(item).find("div.hdinfo")[0]).text().trim(),
                remark = $($(item).find(".module-item-note")[0]).text().trim().replace(/.*分/, "");
            videos.push({
                vod_id: a.attribs.href,
                vod_name: img.attribs.alt,
                vod_pic: img.attribs["data-original"],
                vod_remarks: remark || hdinfo || ""
            })
        }
        return videos
    },
    二级: async function (ids) {
        let { input } = this;
        const html = (await _req(rule.host + ids[0])).content
        const $ = pq(html);
        let vod = {
            vod_name: $(".module-info-heading>h1").text(),
            vod_id: ids[0],
            vod_pic: $(".lazyload:first").attr("data-original"),
            vod_remarks: $(".module-info-item-title:contains(更新)+p").text(),
            vod_content: $(".show-desc").text().trim()
        };
        vod.vod_play_from = $("#y-playList span").map((_, i) => $(i).text()).get().join('$$$');
        vod.vod_play_url = $(".module-play-list-content").map((_, item) => {
            return $(item).find("a").map((_, i) => {
                return $(i).text().replace(/\(.*/, "") + "$" + $(i).attr("href")
            }).get().join("#")
        }).get().join("$$$");
        return vod
    },
    搜索: async function (wd, quick, pg) {
        let { input } = this;
        let ck = await verifyCode(
            rule.host + "/index.php/verify/index.html?",
            {
                url: rule.host + "/index.php/ajax/verify_check?type=search&verify=$code",
                method: "POST",
                headers: {
                    "Content-Type": "application/x-www-form-urlencoded",
                    cookie: "$cookie"
                },
                body: `type=search&verify=$code`
            },
            3
        )
        const searchResp = await _req(input);
        if (searchResp.code > 200) {
            rule.headers.cookie = "";
            throw new Error("搜索错误");
        }
        const html = searchResp.content;
        const $ = pq(html);
        let videos = []
        for (const item of $(".module-items>div")) {
            const img = $(item).find("img:first")[0],
                a = $(item).find("a:first")[0],
                hdinfo = $($(item).find("div.hdinfo")[0]).text().trim(),
                remark = $($(item).find(".module-info-item-content")[0]).text().trim();
            videos.push({
                vod_id: a.attribs.href.replace(/.*?\/movie\/(.*).html/g, "$1"),
                vod_name: img.attribs.alt,
                vod_pic: img.attribs["data-original"],
                vod_remarks: remark || hdinfo || ""
            })
        }
        return videos
    },
    lazy: async function (flag, id, flags) {
        let { input } = this;
        const html = (await _req(rule.host + id)).content;
        eval(html.match(/player_aaaa[\s\S]*?(?=<\/script>)/)[0])
        let purl = "https://api.bytegooty.com//?url=" + player_aaaa.url
        let phtml = (await getHtml(purl)).data;
        const $ = pq(phtml);
        config = eval(phtml.match(/config\s*=[\s\S]*?(?=player)/)[0]);
        let play_url = "";
        try {
            const sortByKey = (_0x2df378, _0x5d56c7, _0x3a5216) => _0x5d56c7.sort(({
                [_0x2df378]: _0x258bb0
            }, {
                [_0x2df378]: _0x58eebd
            }) => _0x3a5216(_0x258bb0, _0x58eebd))
            function decrypt(_0x29c3c3) {
                let _0x9d66e = $("meta[name=\"viewport\"]").attr("id").replace("now_", ""),
                    _0x165aac = $("meta[charset=\"UTF-8\"]").attr("id").replace("now_", ""),
                    _0x5018c6 = [],
                    _0x54916f = [],
                    _0x3a1b2d = "";
                for (var _0x213107 = 0; _0x213107 < _0x165aac.length; _0x213107++) {
                    _0x5018c6.push({
                        "id": _0x165aac[_0x213107],
                        "text": _0x9d66e[_0x213107]
                    });
                }
                _0x54916f = sortByKey("id", _0x5018c6, (_0x104866, _0x524692) => _0x104866 - _0x524692);
                for (var _0x213107 = 0; _0x213107 < _0x54916f.length; _0x213107++) {
                    _0x3a1b2d += _0x54916f[_0x213107].text;
                }
                let _0x266f5a = CryptoJS.MD5(_0x3a1b2d + "3G7Fh9Dp6R2QsE8w").toString(),
                    _0x41106e = CryptoJS.enc.Utf8.parse(_0x266f5a.substring(16)),
                    _0x5adc6c = CryptoJS.enc.Utf8.parse(_0x266f5a.substring(0, 16)),
                    _0x477cb9 = CryptoJS.AES.decrypt(_0x29c3c3, _0x41106e, {
                        "iv": _0x5adc6c,
                        "mode": CryptoJS.mode.CBC,
                        "padding": CryptoJS.pad.Pkcs7
                    });
                return _0x477cb9.toString(CryptoJS.enc.Utf8);
            }
            play_url = decrypt(config.url)
        } catch (error) {
            console.log(error)
        }
        return { parse: 0, url: play_url }
    },
};

const expireTime = 60 * 5 * 1000;  // 设置cookie过期时间，单位毫秒
let timeA = new Date().getTime();
async function _req(url, opt) {
    let timeB = new Date().getTime();
    if (!rule.headers.cookie || timeB - timeA > expireTime) {
        rule.headers.cookie = "";
        rule.headers.cookie = "sl-challenge-jwt=" + await getJwt()
        console.log(`番薯动漫: 获取cookie成功 ${rule.headers.cookie}`);
        timeA = timeB;
    }
    opt = opt || {};
    opt.headers = Object.assign(rule.headers || {}, opt.headers || {})
    opt.timeout = rule.timeout || 5000;
    let resp = await retryRequest(url, opt, resp => {
        if (resp.code === void 0) return true
    }, 4);
    if (resp.headers["set-cookie"]) {
        const cookie = [resp.headers["set-cookie"]].flat(); // string或者array最终生成array
        rule.headers.cookie = cookie.map(it => it.replace(/;.*/, "")).join(";");
        console.log("设置ck成功", rule.headers.cookie);
    }
    return resp;
}

// 重复请求
async function retryRequest(url, opt, cb, num = 1) {
    let resp = {};
    for (let i = 1; i <= num; i++) {
        resp = await req(url, opt);
        if (await cb(resp)) {
            console.log(`retryRequest: ${url} 重复请求 ${i}次`);
            continue;
        }
        break;
    }
    return resp;
}

async function getJwt() {
    return new Promise(async (resolve, reject) => {
        const navigator = {
            userAgent: UA,
            platform: "Win32",
            languages: ['zh-CN', 'en', 'en-GB', 'en-US'],
            vendor: "Google Inc.",
        };
        const screen = {
            width: misc.rand(1536, 1536 + 300),
            height: + misc.rand(864, 864 + 300),
        };
        const wasmBuffer = await axios.get("https://challenge.rivers.chaitin.cn/challenge/v2/calc.wasm", { responseType: 'arraybuffer' });
        const rootResp = await retryRequest("https://www.fsdm02.com/", { headers: { "User-Agent": UA } }, async resp => {
            await sleep(500);
            if (resp.content.match(/502 Bad Gatewa/)) return true
        }, 3);
        const html = rootResp.content;
        const clientId = html.match(/SafeLineChallenge\("(.*?)"/)[1];
        const level = parseInt(html.match(/SafeLineChallenge.*?level:\s*"(\d+)"/)[1], 10);
        const issueJson = (await axios.post("https://challenge.rivers.chaitin.cn/challenge/v2/api/issue", {
            client_id: clientId,
            level
        }, { headers: { "Content-Type": "application/json" } })).data;

        function u(e, t) {
            return ({
                status: "finish",
                issue_id: t.issue_id,
                result: e(t.data)
            })
        }

        WebAssembly.instantiate(wasmBuffer.data).then(({ instance }) => {
            let n = {};
            n.data = (u(function (e) {
                return instance.exports.reset(),
                    e.map(function (e) {
                        return instance.exports.arg(e)
                    }),
                    Array(instance.exports.calc()).fill(-1).map(function () {
                        return instance.exports.ret()
                    })
            }, issueJson.data))
            function generateRandomString(length) {
                const characters = '0123456789abcdefghijklmnopqrstuvwxyz';
                let result = '';
                const charactersLength = characters.length;

                for (let i = 0; i < length; i++) {
                    const randomIndex = Math.floor(Math.random() * charactersLength);
                    result += characters.charAt(randomIndex);
                }

                return result;
            }
            const visitorId = generateRandomString(32);
            axios.post("https://challenge.rivers.chaitin.cn/challenge/v2/api/verify", {
                issue_id: n.data.issue_id,
                result: n.data.result,
                serials: [],
                client: {
                    userAgent: navigator.userAgent,
                    platform: navigator.platform,
                    language: navigator.languages.join(","),
                    vendor: navigator.vendor,
                    screen: [screen.width, screen.height],
                    visitorId,
                    score: 0
                }
            }, {
                headers: {
                    "Referer": "https://www.fsdm02.com/",
                    "Content-Type": "application/json"
                }
            }).then(async resp => {
                if (resp.status === 200) {
                    resolve(resp.data.data.jwt);
                }
                reject("获取jwt失败")
            }).catch(error => console.log(error));
        }).catch(error => console.log(error));
    })
}

async function ocrByb64(b64) {
    const url = OCR_API;
    try {
        let resp = await req(url, {
            method: "POST",
            headers: {
                "Content-Type": "text/plain;charset=UTF-8",
            },
            body: b64
        });
        return {
            isError: false,
            response: resp
        }
    } catch (e) {
        return {
            isError: true,
            response: null
        }
    }

}

async function verifyCode(imgUrl, verifyUrlOpt, num = 1) {
    let cookie = "";
    let count = 0;
    while (true) {
        count++;
        rule.headers.cookie = "";
        let imgResp = await _req(imgUrl, {
            buffer: 2,
        });
        let validate = (await ocrByb64(imgResp.content)).response.content;
        let setCookie = imgResp.headers["set-cookie"];
        cookie = [setCookie].flat().map(it => it.replace(/;.*/, '')).join(";");
        let { url: vurl, ...vopt } = JSON.parse(JSON.stringify(verifyUrlOpt)
            .replace(/\$cookie/g, cookie)
            .replace(/\$code/g, validate)
        )
        let verifyResp = await req(vurl, vopt)
        console.log(`ocr第${count}次 识别结果: ${validate}`);
        console.log("验证结果: " + verifyResp.content);
        if (verifyResp.content.match(/"ok"/)) {
            break;
        }
        if (count >= num) {
            throw Error("验证码识别失败");
        }
    }
    return cookie;
}

(function () {
    'use strict';
    var cookieTemp = "";
    Object.defineProperty(rule.headers, 'cookie', {
        set: function (val) {
            if ((val || "").trim() === "") {
                cookieTemp = "";
            } else {
                const updateCK = cookieToJson(val);
                const cacheCK = cookieToJson(cookieTemp);
                cookieTemp = jsonToCookie(
                    Object.assign(cacheCK, updateCK)
                );
            }
        },
        get: function () {
            return cookieTemp;
        }
    });
})();