import InfoUtils from "../class/utils/InfoUtils";
import MathUtils from "../class/utils/MathUtils";
import NOTIFY_HTML from "../../static/html/buyBeer/notify.html";
import CommonUtils from "../class/utils/CommonUtils";
import Popup from "../class/utils/Popup";
import ResponseInject from "../interface/ResponseInject";
import LocalConfigWrapper from "../class/LocalConfigWrapper";
import ClassName from "../container/ClassName";
import { Injectable } from "../container/Injectable";
import Logger from "../class/Logger";
import MsgWrapper from "../class/utils/MsgWrapper";
import IFeature from "../man/IFeature";
import ATK_PAGE_REG from "./url/ATK_PAGE_REG";
import ALL_PAGE_REG from "./url/ALL_PAGE_REG";

@ClassName('BuyBeerHelper')
@Injectable()
export default class BuyBeerHelper implements BeerMonitorLoop, ResponseInject, IFeature {

    urlIncludes(): RegExp[] {
        return [ALL_PAGE_REG]
    }

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

    description(): string {
        return '啤酒助手'
    }

    iStart(): void | Promise<void> {
        (this.localConfigWrapper.config._15Alarm) && this.start()
    }

    private isNotifying = false;
    private loopId: number = null;
    private time: number;
    private readonly notifyHtml: string = NOTIFY_HTML.replace('{{}}', this.mathUtils.getRandomInt(0, 99).toString());

    public constructor(
        private readonly localConfigWrapper: LocalConfigWrapper,
        private readonly commonUtils: CommonUtils,
        private readonly infoUtils: InfoUtils,
        private readonly mathUtils: MathUtils,
        private readonly logger: Logger,
        private readonly msgWrapper: MsgWrapper,
    ) {
        this.time = this.localConfigWrapper.config._15AlarmTime || 30;
    }

    public start(): void {
        if (this.loopId) {
            this.logger.info('啤酒助手已在运行');
        } else {
            this.logger.info('啤酒助手启动');
            this.loopId = window.setInterval(async () => {
                // 海外取消提醒
                let { isTravelling, isAbroad } = await this.infoUtils.getUserState();
                if (isTravelling || isAbroad) {
                    this.stop();
                    return;
                }
                let dt = new Date();
                // 已选当天不提醒
                const now = [dt.getUTCFullYear(), dt.getUTCMonth(), dt.getUTCDate()];
                const ignore_date = this.localConfigWrapper.config._15_alarm_ignore || '{}';
                if (JSON.stringify(now) === JSON.stringify(ignore_date)) return;
                // 正常提醒
                let m = 14 - (dt.getMinutes() % 15);
                let s = 60 - dt.getSeconds();
                if (m === 0 && s < this.time) {
                    // 如从通知点开，则本次通知跳过
                    if (location.href.includes('clickfromnotify')) {
                        this.isNotifying = true;
                        location.hash = '';
                        return;
                    }
                    // 本次已通知
                    if (this.isNotifying) return;
                    this.isNotifying = true;
                    // 发送通知
                    const rNum = this.mathUtils.getRandomInt(0, 99);
                    // const notify =
                    this.msgWrapper.create(NOTIFY_HTML.replace('{{}}', rNum.toString()), {
                        timeout: 30,
                        sysNotify: true,
                    });
                    document.querySelector('button#wh-rd-btn-' + rNum).addEventListener('click', () => this.skip_today());
                    // notify.getElement().addEventListener('click', ev => {
                    //     if ((ev.target as HTMLElement).tagName.toLowerCase() === 'a') {
                    //         notify.close();
                    //     }
                    // });
                    // 声音提醒
                    {
                        let loop = 3;
                        let id = window.setInterval(async () => {
                            await this.commonUtils.audioPlay();
                            loop--;
                            if (!loop) window.clearInterval(id);
                        }, 800);
                    }
                } else {
                    this.isNotifying = false;
                }
            }, 1000);
        }
    }

    public stop(): void {
        if (this.loopId) {
            window.clearInterval(this.loopId);
            this.loopId = null;
        }
    }

    public set_time(t: number): void {
        this.time = t;
    }

    public status(): '已启动' | '未启动' {
        return this.loopId ? '已启动' : '未启动';
    }

    public is_running(): boolean {
        return this.loopId !== null;
    }

    public skip_today(): void {
        const date = new Date();
        this.localConfigWrapper.config._15_alarm_ignore = [date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()];
        // WuhuConfig.set('_15_alarm_ignore', [date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()], false);
        // 通知
        const rNumber = this.mathUtils.getRandomInt(0, 100);
        const notify = this.msgWrapper.create(`明早8点前将不再提醒 <button id="wh-rd-btn-${ rNumber }">取消</button>`);
        // 通知中的取消按钮
        document.querySelector('#wh-rd-btn-' + rNumber)
            .addEventListener(
                'click',
                () => this.localConfigWrapper.config._15_alarm_ignore.length = 0
            );
    }

    public setTimeHandler(): void {
        let popup = new Popup(`<label>提前提醒时间(秒)：<input type="number" value="${ this.localConfigWrapper.config._15AlarmTime }" /></label><p>区间为 1 ~ 60，默认 50</p>`, '啤酒提醒时间设定');
        let confirm = document.createElement('button');
        confirm.innerHTML = '确定';
        confirm.style.float = 'right';
        confirm.addEventListener('click', () => {
            let input: HTMLInputElement = popup.element.querySelector('input');
            let num = (input.value as any) | 0;
            if (num === this.localConfigWrapper.config._15AlarmTime) return;
            if (num < 1 || num > 60) num = 50;
            input.value = num.toString();
            this.localConfigWrapper.config._15AlarmTime = num;
            this.set_time(num);
            // 之前的运行状态
            if (this.is_running()) this.start();
            popup.close();
        });
        popup.element.appendChild(confirm);
    }

    public responseHandler(url: string, body: { json: unknown; text: string; isModified: boolean }, opt: {
        method: "GET" | "POST";
        requestBody: string
    }) {
        if (url.includes('shops.php') && opt?.method === 'POST') {
            let req = opt.requestBody;
            if (req && req.includes('step=buyShopItem') && req.includes('ID=180') && body.json && body.json['success']) {
                this.msgWrapper.create('检测到已成功购买啤酒');
                this.skip_today();
            }
        }
    }
}

export interface BeerMonitorLoop {
    start?: Function;
    stop?: Function;
    set_time?: Function;
    status?: Function;
    is_running?: Function;
    skip_today?: Function;
}
