/**
 * 应用服务模块
 * @date 2022-03
 * @author 何华东
 */

import { logger } from "mslib";
import { Container, Inject, Singleton } from "typescript-ioc";
import { TyExternalApiClient, GetConfigInfoResponse } from "./TyExternalApi";
import { redisClient } from "./Redis";
import { Sync } from "./Promise";
import { IocConfigProvider } from "./Config";

let basic_config = IocConfigProvider.getBasicConfig();

/**
 * app应用服务
 */
@Singleton
export default class AppService {
    @Inject
    tyExternalApiClient: TyExternalApiClient;

    configInfo = null;
    refresh_configInfo_interval = null;

    /**
     * 获取appid配置信息，redis缓存
     * 
     * 缓存优先，同步执行，减少对统一接口调用
     * @param ex redis缓存时间(秒)
     */
    @Sync()
    async getConfigInfo(ex?: number): Promise<GetConfigInfoResponse> {
        if (!basic_config?.tapdId) throw new Error(`ioc未配置基础配置tapdId`);

        let key = `${basic_config.tapdId}_configInfo`;

        try {
            let value = await redisClient.get(key);
            if (value !== null) return JSON.parse(value);
        } catch (error) {
            logger.error(error);
        }

        let configInfo = await this.tyExternalApiClient.getConfigInfo();

        try {
            await redisClient.set(key, JSON.stringify(configInfo), 'ex', ex || 60 * 30);
        } catch (error) {
            logger.error(error);
        }

        return configInfo;
    }

    /**
     * 查找匹配的车场配置(redis缓存)
     */
    async findParkExtendConfig(parkId: any) {
        let configInfo = await this.getConfigInfo();
        return configInfo?.parkConfig?.find(s => s.stcParkId === parkId?.toString() || s.parkId?.toString() === parkId?.toString());
    }

    /**
     * 获取匹配的车场配置(redis缓存)，未找到会抛出异常
     */
    async getParkExtendConfig(parkId: any) {
        let parkExtendConfig = await this.findParkExtendConfig(parkId);
        if (!parkExtendConfig) throw `未匹配到车场`;

        return parkExtendConfig;
    }

    /**
     * 获取appid配置信息，本地缓存（缓存5分钟）
     */
    @Sync()
    async getConfigInfoFromLocal(): Promise<GetConfigInfoResponse> {
        if (this.configInfo) return this.configInfo;

        let configInfo = await this.tyExternalApiClient.getConfigInfo();
        this.configInfo = configInfo;

        if (!this.refresh_configInfo_interval) {
            this.refresh_configInfo_interval = setInterval(async () => {
                try {
                    let configInfo = await this.tyExternalApiClient.getConfigInfo();
                    this.configInfo = configInfo;
                } catch (error) {
                    logger.error(`定时刷新车场配置信息失败`, error);
                }
            }, 1000 * 60 * 5);
        }

        return this.configInfo;
    }

    /**
     * 查找匹配的车场配置(本地缓存)
     */
    async findParkConfigFromLocal(parkId: any) {
        let configInfo = await this.getConfigInfoFromLocal();
        return configInfo?.parkConfig?.find(s => s.stcParkId === parkId?.toString() || s.parkId?.toString() === parkId?.toString());
    }

    /**
     * 获取匹配的车场配置(本地缓存)，未找到会抛出异常
     */
    async getParkConfigFromLocal(parkId: any) {
        let config = await this.findParkConfigFromLocal(parkId);
        if (!config) throw `未匹配到车场`;

        return config;
    }
}

export { AppService }