import { LoggerParam, Config } from './types'
import { getCache, getInitPlatform, setCache, getLaunchTime, request } from './util'
import { EID, EVENT_TYPE } from './enums'
import { ELES_CLICK, LAUNCH_TIME_KEY, LOGGER_DID_KEY } from './constant'
import { LoggerImpl } from './LoggerImpl'
import { v4 as uuid4 } from 'uuid'
import { getLogInfo, getUser } from '@/pages/api/base'
import axios from 'axios'
import { IS_LOCAL } from '../constans/international'

export * from './types'
export * from './enums'

axios.defaults.withCredentials = true
axios.defaults.timeout = 60000
class Logger implements LoggerImpl {
    constructor() {
        this.EVENT_TYPE = EVENT_TYPE
        this.EID = EID
        this.config = {
            platform: getInitPlatform(),
            logUrl: '',
            clickEles: ELES_CLICK,
        }
        this.DID = IS_LOCAL ? '' : getCache('did') || ''
        this.dontReport = IS_LOCAL ? true : false
        this.init()
    }

    EVENT_TYPE: typeof EVENT_TYPE

    EID: typeof EID

    public DID: string

    public config: Config

    /**
     * 用户id，未登录为undefined
     */
    private uid?: string

    private version?: string

    private dontReport?: boolean

    public setGlobalConfig(config: Config): void {
        this.config = {
            ...this.config,
            ...config,
        }
    }

    /**
     * 获取设备id
     * @returns
     */
    private async getDId(): Promise<string> {
        if (IS_LOCAL) {
            // 本地版从后端取did和version
            const info = await getLogInfo()
            if (info.did) {
                this.version = info.version
                this.dontReport = !info.logAgreed
                return info.did
            }
            return ''
        } else {
            const cacheDid = getCache(LOGGER_DID_KEY)
            if (cacheDid?.did) {
                return cacheDid?.did
            }
            //  前端生成一个did

            const did = uuid4()

            if (did) {
                setCache(LOGGER_DID_KEY, { did })
                return did
            }
            return ''
        }
    }

    /**
     * 初始化
     */
    private async init(): Promise<void> {
        // 获取设备id
        if (!this.DID) {
            try {
                this.DID = await this.getDId()
            } catch (error) {
                console.warn('did error', error)
            }
        }
        if (!this.uid) {
            try {
                this.uid = await this.getUid()
            } catch (error) {
                console.warn('uid error', error)
            }
        }

        /**
         *  注册页面加载事件
         */
        await this.regOnLoad()
    }

    /**
     * 获取用户id
     * @returns
     */
    private async getUid(): Promise<string | undefined> {
        if (IS_LOCAL) {
            return ''
        } else {
            try {
                const value = await getUser({ noLogin: true })
                if (value) {
                    return value?.uid
                }
            } catch (error) {
                return ''
            }
        }
    }

    public getParams(
        eid?: string,
        event_type?: number,
        ext?: Record<string, any>,
    ): Partial<LoggerParam> {
        return {
            eid,
            event_type,
            ext: this.version
                ? {
                      ...ext,
                      version: this.version,
                  }
                : ext,
            time: Date.now(),
            refer_url: document.referrer,
            url: location.href,
            platform: this.config.platform,
            did: this.DID,
            launch_time: getLaunchTime(LAUNCH_TIME_KEY) || Date.now(),
            uid: this.uid,
            localVersion: IS_LOCAL || false,
        }
    }

    public log(args: Array<LoggerParam> | LoggerParam): Promise<any> {
        if (this.dontReport) return Promise.resolve(null)
        return request(this.config.logUrl, { method: 'POST' }, args, {})
    }

    /**
     *
     * 页面加载，引入logger 500ms秒之后，必然是打开了页面
     * @returns {Promise<void>}
     */
    public async regOnLoad(): Promise<void> {
        return new Promise((resolve) => {
            setTimeout(async () => {
                const pageStay = '打开页面上报'
                console.time(pageStay)
                console.log('打开页面上报...')
                await this.log({ eid: this.EID.BLANK, event_type: this.EVENT_TYPE.CLICK_BLANK })
                console.timeEnd(pageStay)
                resolve()
            }, 500)
        })
    }

    /**
     * 单例
     * @returns {LoggerInstance}
     */
    static getInstance(): LoggerInstance {
        if (window?.logger instanceof Logger) return window.logger
        const logger: LoggerInstance = new Logger()
        window.logger = logger
        return logger
    }
}

const logger = Logger.getInstance()

export { Logger, logger }
