import TornStyleBlock from "../utils/TornStyleBlock";
import InfoUtils from "../utils/InfoUtils";
import FetchUtils from "../utils/FetchUtils";
import CommonUtils from "../utils/CommonUtils";
import MathUtils from "../utils/MathUtils";
import ClassName from "../../container/ClassName";
import { Injectable } from "../../container/Injectable";
import Logger from "../Logger";
import IFeature from "../../man/IFeature";

/**
 * 老虎机批量购买助手
 */
@ClassName("SlotsHelper")
@Injectable()
export default class SlotsHelper implements IFeature {
    description(): string {
        return "老虎机批量购买助手";
    }

    iStart(): void | Promise<void> {
        this.init()
    }

    urlExcludes(): RegExp[] {
        return [];
    }

    urlIncludes(): RegExp[] {
        return [/loader\.php\?sid=slots/];
    }

    constructor(
        private readonly mathUtils: MathUtils,
        private readonly commonUtils: CommonUtils,
        private readonly fetchUtils: FetchUtils,
        private readonly infoUtils: InfoUtils,
        private readonly logger: Logger,
    ) {
    }

    private block = new TornStyleBlock("芜湖助手");

    // 载入
    public init() {
        this.block.insert2Dom();
        let nodes = this.createNodes();
        this.block.append(nodes.root);
        this.block.getBase().insertAdjacentHTML(
            'beforeend',
            '<style>#wh-slots-cont input{padding:0.5em;}' +
            '#wh-slots-cont select{margin:0.5em;min-width: 3em;}</style>'
        )
    }

    private createNodes(): SlotsHelperNodes {
        let root = document.createElement('div');
        root.id = 'wh-slots-cont';

        // 购买数量输入框
        let counterInput = document.createElement('input');
        counterInput.type = 'number';
        // counterInput.value = '1';
        counterInput.placeholder = '数量';

        // 老虎机按钮类型 对应单价
        let select = document.createElement('select');
        ['10', '100', '1k', '10k', '100k', '1m', '10m'].forEach(option => select.innerHTML += `<option>${ option }</option>`);

        // 开始按钮
        let goBtn = document.createElement('button');
        goBtn.innerHTML = ' GO ';
        goBtn.classList.add('torn-btn');

        // 消息框
        let msgBox = document.createElement('div');

        root.append(counterInput, select, goBtn, msgBox);

        let ret = { root, counterInput, select, goBtn, msgBox };
        goBtn.addEventListener('click', async ev => {
            goBtn.disabled = true;
            try {
                await this.goBtnHandler(ev, ret)
            } catch (e) {
                this.logger.error(e.stack || e);
            }
            goBtn.disabled = false;
        });

        return ret;
    }

    // 按键点击处理方法
    private async goBtnHandler(ev: MouseEvent, nodes: SlotsHelperNodes) {
        let { counterInput, select, msgBox } = nodes;
        // 现金
        let cash = (await this.infoUtils.getSessionData())?.user?.money?.value;
        msgBox.innerText = '等待加载中';
        // 代币
        let tokens: number = parseInt((await CommonUtils.querySelector('.player-info-cont #tokens')).innerText);
        // 输入的购买数量
        let count = parseInt(counterInput.value);
        // 用户选中的单价
        let price = [10, 100, 1000, 10000, 100000, 1000000, 10000000][select.selectedIndex];
        if (cash < count * price || tokens < count) {
            msgBox.innerText = '现金或代币不足';
            throw new Error("现金或代币不足");
        }
        if (!count) {
            msgBox.innerText = '输入有误';
            throw new Error("输入有误");
        }
        // 总赢
        let wonTotal = 0;
        // 实际购买数量
        let i: number;
        for (i = 0; i < count; i++) {
            let res: SlotsResponse = await (await this.fetchUtils.ajaxFetch({
                url: window.addRFC("https://www.torn.com/loader.php?sid=slotsInterface&step=play&stake=" + price),
                referrer: "/loader.php?sid=slots",
                method: "GET"
            })).json();
            wonTotal += res.moneyWon;
            msgBox.innerText = `当前第${ i + 1 }轮, 共赢 $${ wonTotal }`;
            if (res.tokens === 0) {
                msgBox.innerHTML += '<br/>代币不足';
                break;
            }
            await this.commonUtils.sleep(this.mathUtils.getRandomInt(1800, 2400));
        }
        // 利润
        let profit = wonTotal - i * price;
        // 大于10m
        let bang = Math.abs(profit) > 10000000;
        msgBox.innerHTML += '<br/>已停止, ';
        msgBox.innerHTML += bang ? '血' : '小';
        msgBox.innerHTML += profit > 0 ? '赚' : '亏';
        this.logger.info("[goBtnHandler]结束", { cash, tokens, count, price, wonTotal });
    }
}

interface SlotsHelperNodes {
    root: HTMLDivElement,
    counterInput: HTMLInputElement,
    select: HTMLSelectElement,
    goBtn: HTMLButtonElement,
    msgBox: HTMLDivElement
}

// 返回格式
interface SlotsResponse {
    moneyWon: number,
    tokens: number
}
