import InventoryItemInfo from "../../interface/responseType/InventoryItemInfo";
import FetchUtils from "./FetchUtils";
import CommonUtils from "./CommonUtils";
import PriceData from "../../interface/PriceData";
import Asyncable from "../../interface/Asyncable";
import ClassName from "../../container/ClassName";
import { Injectable } from "../../container/Injectable";
import Logger from "../Logger";
import { InjectionKey } from "vue";

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

    constructor(
        private readonly fetchUtils: FetchUtils,
        private readonly logger: Logger,
    ) {
    }

    /** 保存物品名-ID对应关系 */
    private itemNameMap: { [name: string]: number } = null;

    itemValueMap: { [k: string]: Partial<InventoryItemInfo> } = {
        'Glass of Beer': {
            itemName: '一杯啤酒',
            itemInfo: '[译]Only savages drink beer straight out of the bottle. This glass of beer is obtained fresh from the keg, and provides the same level of drunken joy as you\'d get from a regular bottle of suds. Provides a moderate nerve increase when consumed.',
            itemInfoContent: "<div class='m-bottom10'>" +
                "<span class=\"bold\">一杯啤酒</span> 是酒类物品" +
                "</div>" +
                "Only savages drink beer straight out of the bottle. This glass of beer is obtained fresh from the keg, and provides the same level of drunken joy as you'd get from a regular bottle of suds. Provides a moderate nerve increase when consumed." +
                "<div class=\"t-green bold item-effect m-top10\">效果: 犯罪 + 2，增幅CD + 1h。</div>",
        },
    };

    itemPriceMap = {
        205: { name: 'Vicodin', price: 1300 },
    };

    // 缓存过期时间 分钟
    private readonly priceTimeout = 720;

    /** TODO 通过 name 查询 */
    public async getItemData(idOrName: string): Promise<Partial<InventoryItemInfo>> {
        let _itemId: number = null;
        try {
            _itemId = parseInt(idOrName);
        } finally {
        }
        let itemId: number;
        if (this.itemNameMap) {
            itemId = _itemId || this.itemNameMap[idOrName];
        } else {
            itemId = (await this.getItemNameMap().promise)[idOrName];
        }
        return await (await this.fetchUtils.ajaxFetch({
            url: '/inventory.php',
            method: 'POST',
            body: JSON.stringify({
                step: 'info',
                itemID: itemId,
                armouryID: 0
            }),
            referrer: 'displaycase.php',
        })).json();
    }

    /**
     * 物品查价-缓存
     * @param idOrName
     */
    public getItemPrice(idOrName) {
    }

    /**
     * 物品查价-API
     * @param idOrName
     */
    public getItemPriceApi(idOrName) {
    }

    /**
     * 物品查价值
     */
    public async getItemValue(idOrName) {
        return (await this.getItemData(idOrName)).itemValue.replaceAll(/[,$]/g, '');
    }

    /** 返回本地物品价格数据，id对应物品名和价格 */
    public getLocalPriceData(): Asyncable<PriceData["data"]> {
        // 获取本地缓存
        let localStore = localStorage.getItem('WHItemPrice');
        let res = { data: null, promise: null };
        let data: PriceData = null;
        // 无缓存
        if (!localStore) {
            res.promise = this.fetchPriceData();
            return res;
        }
        // 解析缓存
        try {
            data = JSON.parse(localStore);
        } catch (e) {
            this.logger.error(e.stack || e.message || e);
            throw new Error('JSON解析错误');
        }
        // 缓存超时
        if (Date.now() - data.timestamp > this.priceTimeout * 60000) {
            res.data = null;
            res.promise = this.fetchPriceData();
        } else {
            res.data = data.data;
            res.promise = null;
        }
        return res;
    }

    /** 返回物品名与id对应关系 */
    public getItemNameMap(): Asyncable<{ [key: string]: number }> {
        let localData = this.getLocalPriceData();
        let ret: Asyncable<{ [key: string]: number }> = {
            data: null,
            promise: null
        };
        // 有缓存
        if (localData.data || this.itemNameMap) {
            // 内存缓存
            if (this.itemNameMap) {
                ret.data = this.itemNameMap;
            }
            // 本地缓存
            else {
                ret.data = {};
                Object.keys(localData.data).forEach((k) => {
                    ret.data[localData.data[k].name] = parseInt(k);
                });
                this.itemNameMap = ret.data;
            }
        }
        // 无缓存异步返回
        else {
            ret.promise = new Promise(async resolve => {
                let response = await localData.promise;
                this.logger.info({ response });
                let promiseRet = {};
                Object.keys(response).forEach(k => {
                    promiseRet[response[k].name] = k;
                });
                this.itemNameMap = promiseRet;
                resolve(promiseRet);
            });
        }
        return ret;
    }

    /**
     * fetch方法，返回后加入本地缓存，返回格式: 物品id ->
     * `{name: string, price: number}`
     */
    private async fetchPriceData(): Promise<PriceData["data"]> {
        let res = null;
        // 获取在线价格
        try {
            res = JSON.parse(await CommonUtils.COFetch('https://jjins.github.io/item_price_raw.json'))
        } catch (err) {
            this.logger.error(err.stack || err.message || err);
            throw new Error('获取在线价格时出错');
        }
        // 更新缓存
        let localData: PriceData = {
            timestamp: Date.now(),
            data: res,
        };
        localStorage.setItem('WHItemPrice', JSON.stringify(localData));
        return res;
    }
}

export const ItemHelperKey = Symbol('ItemHelperKey') as InjectionKey<ItemHelper>;
