import { v4 } from 'uuid'
import { useLoginStore } from '@/stores'
import service from '@/services'
import eventBus from '@/services/bus'
import Socket from './build'
import { RequestCode, MessageType } from './build/types'

export default new (class {
    /** 行情链路 */
    private socket?: Socket;

    /** 行情订阅集合 */
    private subscribeMap = new Map<string, string[]>()

    private async connect() {
        if (!this.socket) {
            await service.onReady()
            const quoteUrl = service.getConfig('quoteUrl')
            this.socket = new Socket(quoteUrl, {
                heartbeat: true,
            })

            this.socket.onReconnect = () => {
                // 重新订阅商品
                this.subscribe()
            }

            this.socket.onPush = ({ data }) => {
                // 推送实时行情通知
                eventBus.$emit('QuotePush', data)
            }
        }
        return this.socket
    }

    /**
     * 开始行情订阅
     */
    private subscribe = () => {
        const subscribeData: string[] = []
        this.subscribeMap.forEach((list) => {
            subscribeData.push(...list)
        })

        if (subscribeData.length) {
            console.log('开始行情订阅', subscribeData)
            this.connect().then((ws) => {
                ws.send({
                    headers: {
                        requestId: v4(),
                        requestCode: RequestCode.QuoteSubscribe,
                        messageType: MessageType.Push,
                    },
                    data: subscribeData
                }).then((res) => {
                    console.log('行情订阅成功', res)
                }).catch((err) => {
                    console.error('行情订阅失败', err)
                })
            })
        } else {
            // 没有订阅的时候，断开连接
            this.close()
        }
    }

    /**
     * 添加行情订阅
     * @param goodsCodes 
     * @param key 
     * @returns 
     */
    addSubscribe = (goodsCodes: string[], key?: string) => {
        const loginStore = useLoginStore()
        const uuid = key ?? v4()
        const value = this.subscribeMap.get(uuid) ?? []

        const start = () => {
            if (loginStore.token) {
                // 对相同 key 订阅的商品进行合并处理
                this.subscribeMap.set(uuid, [...value, ...goodsCodes])
                this.subscribe()
            }
        }

        return {
            uuid,
            start,
            stop: () => {
                const flag = this.subscribeMap.delete(uuid)
                if (flag) {
                    console.log('删除订阅', uuid)
                }
                if (loginStore.token) {
                    this.subscribe()
                }
                return flag
            },
        }
    }

    /**
     * 删除行情订阅
     * @param keys 
     */
    removeSubscribe = (...keys: string[]) => {
        if (keys.length) {
            keys.forEach((key) => {
                if (this.subscribeMap.delete(key)) {
                    console.log('删除订阅', key)
                }
            })
        } else {
            console.log('取消订阅')
            this.subscribeMap.clear()
        }
        this.subscribe()
    }

    /**
     * 关闭行情链路
     */
    close() {
        this.socket?.close()
    }
})