import ISidebarData from "../../interface/ISidebarData";
import FetchUtils from "./FetchUtils";
import ClassName from "../../container/ClassName";
import { Injectable } from "../../container/Injectable";
import Logger from "../Logger";
import LocalConfigWrapper from "../LocalConfigWrapper";
import MsgWrapper from "./MsgWrapper";
import { ElMessageBox } from "element-plus";
import { MessageBoxData } from "element-plus/es/components/message-box/src/message-box.type";

@ClassName('InfoUtils')
@Injectable()
export default class InfoUtils {

    constructor(
        // TODO 循环依赖
        // private readonly commonUtils: CommonUtils,
        private readonly fetchUtils: FetchUtils,
        private readonly logger: Logger,
        private readonly localConfigWrapper: LocalConfigWrapper,
        private readonly msgWrapper: MsgWrapper,
    ) {
    }

    /**
     * 返回玩家信息的对象 { playername: string, userID: number }
     * @return {PlayerInfo} rs
     */
    public getPlayerInfo(): PlayerInfo {
        const node = document.querySelector('script[uid]');
        if (node) {
            return {
                playername: node.getAttribute('name'),
                userID: parseInt(node.getAttribute('uid')),
            }
        } else {
            // 自动登陆
            const { autoLoginEmail, autoLoginPwd } = this.localConfigWrapper.config;
            if (autoLoginEmail && autoLoginPwd) {
                window.setTimeout(async () => {
                    let alertRs: MessageBoxData = null;
                    try {
                        alertRs = await ElMessageBox.confirm(
                            '可进行自动登录',
                            '确认',
                            {
                                confirmButtonText: '好',
                                cancelButtonText: '算了',
                                type: 'info',
                            }
                        )
                    } catch (e) {
                    }
                    if (alertRs !== 'confirm') return;
                    this.msgWrapper.create('正尝试自动登录...', null, 'info');
                    await fetch("https://www.torn.com/page.php?sid=Auth", {
                        "headers": {
                            "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
                            "cache-control": "no-cache",
                            "content-type": "application/x-www-form-urlencoded",
                            "pragma": "no-cache",
                            "sec-ch-ua-mobile": "?0",
                            "sec-fetch-dest": "document",
                            "sec-fetch-mode": "navigate",
                            "sec-fetch-site": "same-origin",
                            "sec-fetch-user": "?1",
                            "upgrade-insecure-requests": "1"
                        },
                        "referrer": "https://www.torn.com/",
                        "referrerPolicy": "strict-origin-when-cross-origin",
                        "body": `email=${ autoLoginEmail }&password=${ autoLoginPwd }&redirectUrl=https%3A%2F%2Fwww.torn.com%2F&btnLogin=Login`,
                        "method": "POST",
                        "mode": "cors",
                        "credentials": "include"
                    });
                    this.msgWrapper.create('自动登录完成，即将转跳', null, 'info');
                    window.setTimeout(() => window.location.href = '//www.torn.com/index.php', 1000);
                }, 0);
            }
            this.msgWrapper.create('错误：芜湖助手无法获取用户数据，已退出', null, 'error');
            throw new TypeError('芜湖助手无法获取用户数据');
        }
    }

    /**
     * 返回玩家的部分实时数据
     */
    public async getSessionData(): Promise<ISidebarData> {
        let field: string = 'sidebarData' + this.getPlayerInfo().userID;
        let ret: ISidebarData = {};
        return new Promise(async resolve => {
            let c = 0;
            while (!sessionStorage.getItem(field) && c < 50) {
                c++;
                // await (async () => await this.commonUtils.sleep(10))();
                await (async () => window.setTimeout(() => Promise.resolve(), 10))();
            }
            if (sessionStorage.getItem(field)) {
                try {
                    ret = JSON.parse(sessionStorage.getItem(field));
                } catch (e) {
                    this.logger.error('解析出错', e.stack || e.message || e);
                    ret = {};
                }
            } else {
                this.logger.info('无法从sessionStorage获取数据')
                ret = await (await this.fetchUtils.ajaxFetch({
                    url: window.addRFC('/sidebarAjaxAction.php?q=getSidebarData'),
                    method: 'POST',
                })).json();
                sessionStorage.setItem(field, JSON.stringify(ret));
            }
            try {
                ret.headerData = JSON.parse(sessionStorage.getItem('headerData'));
            } catch (e) {
                this.logger.error('解析出错', e.stack || e.message || e);
                ret.headerData = null;
            }
            resolve(ret);
        });
    }

    /**
     * 返回玩家当前的边栏菜单列表 如gym crimes
     */
    public async getSidebarData() {
        return (await this.getSessionData()).areas;
    }

    /**
     * 玩家的基础信息
     * {status: string, isLoggedIn: boolean, isDonator: boolean, isTravelling: boolean, isAbroad: boolean}
     */
    public async getUserState() {
        return (await this.getSessionData()).headerData.user.state;
    }
}
