const puppeteer = require('puppeteer');
const getCaptcha = require('../Captcha/tesseract');
const axios = require('axios');

class icCookie {
    constructor() {
        console.log('启动浏览器服务')
        this.browser = 0
    }

    async getLoginUrl() {
        return new Promise(async (resolve, reject) => {
            const url1 = 'https://ic.ctbu.edu.cn/ic-web/auth/address?finalAddress=https:%2F%2Fic.ctbu.edu.cn&errPageUrl=https:%2F%2Fic.ctbu.edu.cn%2F%23%2Ferror&manager=false&consoleType=16';

            try {
                const res1 = await axios.get(url1, {
                    maxRedirects: 5, // 增加最大重定向次数
                    validateStatus: function (status) {
                        return (status >= 200 && status < 300) || status === 302; // 接受 302 重定向
                    }
                });

                let redirectUrl = res1.data.data || res1.headers.location;

                if (!redirectUrl) {
                    reject('无法获取登录 URL');
                    return;
                }

                resolve(redirectUrl);
            } catch (error) {
                if (error.response) {
                    const redirectUrl = error.response.headers.location;
                    if (redirectUrl) {
                        resolve(redirectUrl);
                    } else {
                        reject(error);
                    }
                } else {
                    reject(error);
                }
            }
        });
    }

   async refresh(page) {
        page.evaluate(async () => {
            // window.location.reload();
            await refreshCode();
        });
    }

    async getAuthcode(page) {
        return new Promise(async (resolve, reject) => {
            try {
                let base64Image = '';
                const url = await this.getLoginUrl();
                page.goto(url);
                page.on('response', async (response) => {
                    if (response.url().includes('kaptcha?time=')) {
                        const buffer = await response.buffer();
                        base64Image = buffer.toString('base64');

                        const authcodeResult = await getCaptcha(base64Image);
                        if (!authcodeResult.success) {
                            return await this.refresh(page);
                        }

                        const authcode = authcodeResult.msg;
                        resolve(authcode);
                    }
                });

                // 超时处理
                setTimeout(async () => {
                    if (base64Image === '') {
                        await this.refresh(page);
                    }
                }, 5000);
            } catch (error) {
                console.log(error.stack)
                reject(error);
            }
        });
    }

    async tryLogin(page, username, password, authcode) {
        return new Promise(async (resolve, reject) => {
            try {
                await page.waitForSelector('#username');
                await page.waitForSelector('#authcode');
                await page.waitForSelector('#password');
                await page.waitForSelector('#fm1');

                await page.evaluate(async (username, password, authcode) => {
                    document.querySelector("#username").value = username;
                    document.querySelector("#authcode").value = authcode;

                    function checkForm() {
                        var key = new RSAUtils.getKeyPair(public_exponent, "", Modulus);
                        var reversedPwd = password.split("").reverse().join("");
                        var encrypedPwd = RSAUtils.encryptedString(key, reversedPwd);

                        document.querySelector("#password").value = encrypedPwd;
                        document.querySelector("#fm1").submit();

                        return { public_exponent, Modulus, encrypedPwd, authcode };
                    }
                    return checkForm();
                }, username, password, authcode);

                // 响应处理
                page.on('response', async (response) => {
                    if (response.status() >= 300 && response.status() < 400) {
                        return resolve();
                    }

                    if (response.url().includes('login?v=')) {
                        const responseText = await response.text();
                        if (responseText.includes('验证码输入有误') || responseText.includes('必须录入验证码')) {
                            reject({ code: -603, msg: '验证码输入有误' });
                        } else if (responseText.includes('用户名或密码错误')) {
                            reject({ code: -600, msg: '用户名或密码错误' });
                        } else if (responseText.includes('锁定')) {
                            reject({ code: -601, msg: '账户被锁定' });
                        } else {
                            reject({ code: -604, msg: '未知错误' });
                        }
                    }
                });
            } catch (error) {
                reject({ code: -602, msg: error.message });
            }
        });
    }

    async loading(username, password) {
        if (this.browser.length >= 5) {
            return { code: -666, msg: '并发数量达到上限，请稍后再试' };
        }

        let browser;
        this.browser += 1
        try {
            browser = await puppeteer.launch({
                headless: true,
                timeout: 60000
            });

            const page = await browser.newPage();

            page.setDefaultTimeout(30000);

            const authcode = await this.getAuthcode(page);

            await this.tryLogin(page, username, password, authcode);
            let cookie = await this.getCookie(page);
            
            cookie = cookie.split(';')[0]

            return { code: 0, msg: cookie };
        } catch (error) {
            console.error('登录过程错误:', error);
            return { code: -600, msg: error.message };
        } finally {
            this.browser -= 1
            if (browser) {
                await browser.close();
            }
        }
    }

    async getCookie (page) {
        return new Promise((resolve, reject) => {
            page.on('response', async response => {
                if (response.url().includes('https://ic.ctbu.edu.cn/ic-web//auth/token?uuid=')) {
                    // 获取响应头中的 Set-Cookie
                    const cookies = response.headers()['set-cookie'];

                    if (cookies) {
                        resolve(cookies); 
                    } else {
                        reject('No cookies found in response headers');
                    }
                }
            });
        });
    };
}

let IcCookie = new icCookie()
module.exports = IcCookie;
