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

/**
 * 彩票助手
 */
@Injectable()
@ClassName('LotteryHelper')
export default class LotteryHelper implements IFeature {
    private readonly logger: Logger = Logger.factory(LotteryHelper)

    description(): string {
        return "彩票助手";
    }

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

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

    private loopFlag = true;

    private radioDaily: HTMLInputElement = null;
    private radioWeekly: HTMLInputElement = null;
    private radioMonthly: HTMLInputElement = null;
    private time: HTMLInputElement = null;
    private startBtn: HTMLButtonElement = null;
    private stopBtn: HTMLButtonElement = null;
    private progressBar: HTMLElement = null;
    private status: HTMLElement = null;
    private desc: HTMLElement = null;

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

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

    public init() {
        let startTime = new Timer();
        this.logger.info('彩票助手初始化开始');

        let radioLabelDaily = document.createElement('label');
        let radioLabelWeekly = document.createElement('label');
        let radioLabelMonthly = document.createElement('label');
        this.radioDaily = document.createElement('input');
        this.radioWeekly = document.createElement('input');
        this.radioMonthly = document.createElement('input');
        this.time = document.createElement('input');
        this.startBtn = document.createElement('button');
        this.stopBtn = document.createElement('button');
        this.progressBar = document.createElement('div');
        this.status = document.createElement('div');
        this.desc = document.createElement('p');
        let {
            radioDaily,
            radioWeekly,
            radioMonthly,
            time,
            startBtn,
            stopBtn,
            progressBar,
            status,
            desc
        } = this;
        let progressBarBg = document.createElement('div');

        radioDaily.type = 'radio';
        radioDaily.name = 'lottery_type';
        radioDaily.checked = true;
        radioWeekly.type = 'radio';
        radioWeekly.name = 'lottery_type';
        radioMonthly.type = 'radio';
        radioMonthly.name = 'lottery_type';
        time.type = 'number';
        time.placeholder = '填入购买数量';
        time.style.padding = '0.5em';
        time.style.margin = '0 0 0.5em 0.5em';
        startBtn.innerHTML = '开始';
        startBtn.addEventListener('click', () => this.start());
        startBtn.classList.add('torn-btn');
        stopBtn.innerHTML = '终止';
        stopBtn.disabled = true;
        stopBtn.addEventListener('click', () => this.stop());
        stopBtn.classList.add('torn-btn');
        progressBarBg.style.width = '100%';
        progressBarBg.style.height = '1em';
        progressBarBg.style.backgroundColor = '#cecece';
        progressBarBg.style.marginTop = '1em';
        progressBar.style.width = '0';
        progressBar.style.height = '1em';
        progressBar.style.backgroundColor = '#00ff00';
        progressBar.style.marginTop = '-1em';
        progressBar.style.marginBottom = '1em';
        status.innerHTML = '0/0';
        status.style.marginTop = '-2em';
        status.style.textAlign = 'center';
        desc.style.marginTop = '1em';
        desc.innerHTML = '批量买彩票';

        radioLabelDaily.append(radioDaily);
        radioLabelDaily.append(' 日彩 $100');
        radioLabelDaily.style.marginLeft = '0.5em';
        radioLabelWeekly.append(radioWeekly);
        radioLabelWeekly.append(' 周彩 $10k');
        radioLabelMonthly.append(radioMonthly);
        radioLabelMonthly.append(' 月彩 $1m');

        // container.append(title,
        new TornStyleBlock('彩票助手').append(
            radioLabelDaily, radioLabelWeekly, radioLabelMonthly, document.createElement('br'),
            time, document.createElement('br'),
            startBtn, stopBtn,
            progressBarBg, progressBar, status, desc).insert2Dom();
        // document.querySelector('#websocketConnectionData').after(container);

        this.logger.info('彩票助手初始化结束，耗时：' + startTime.getTimeMs());
    }

    private async start() {
        let startTime = new Timer();
        this.loopFlag = true;
        this.stopBtn.disabled = false;
        this.startBtn.disabled = true;
        let rsMsg = null;

        let inputNumber = parseInt(this.time.value);
        if (inputNumber > 0) {
            let msg = document.querySelector('.info-msg-wrap .msg').innerText.trim().split(' ');
            let current = {
                money: (await this.infoUtils.getSessionData()).user.money.value,
                token: parseInt(msg[4])
            };
            let lotteryType = 1;
            if (this.radioWeekly.checked) lotteryType = 2;
            else if (this.radioMonthly.checked) lotteryType = 3;
            // 共计花费
            let totalCost = [null, 100, 10000, 1000000][lotteryType] * inputNumber;
            if (totalCost <= current.money && inputNumber <= current.token) {
                this.desc.innerHTML = '正在开始';
                this.status.innerHTML = `0/${ inputNumber }`;
                this.progressBar.style.width = '0';
                let i = 0;
                while (i < inputNumber) {
                    if (!this.loopFlag) {
                        rsMsg = `终止操作，已完成${ i }/${ inputNumber }`;
                        break;
                    }
                    await this.fetchUtils.ajaxFetch({
                        url: window.addRFC('https://www.torn.com/loader.php?sid=lotteryPlay&step=buyTicket&lotteryID=' + lotteryType),
                        method: 'GET',
                        referrer: '/loader.php?sid=lottery',
                    });
                    await this.commonUtils.sleep(this.mathUtils.getRandomInt(20, 50));
                    i++;
                    this.desc.innerHTML = `已买${ i }张彩票`;
                    this.status.innerHTML = `${ i }/${ inputNumber }`;
                    this.progressBar.style.width = ((i / inputNumber * 100) | 0) + '%';
                }
                if (this.loopFlag) rsMsg = '批量购买完成';
            } else {
                rsMsg = '代币或现金不足';
                this.logger.warn({ totalCost, inputNumber });
            }
        } else {
            rsMsg = '输入有误';
        }

        this.desc.innerHTML = '结束: ' + (rsMsg ? rsMsg + '<br/>耗时：' + startTime.getTimeMs() : '出错了');

        this.stopBtn.disabled = true;
        this.startBtn.disabled = false;
    }

    private stop() {
        this.loopFlag = false;
        this.stopBtn.disabled = true;
        this.startBtn.disabled = false;
    }
}