import { reactive } from "vue"
import type { MessageOptions, MessageInstance } from "./type"
import defaultConfig from "~/config/defaultConfig"
/*
* 思路
* 1. 外层message存储一个个进入队列的消息
* 2. 每个消息实例包含定时器，定时器到时间自动销毁
* 3. 每个消息实例包含暂停和恢复定时器的方法
* 4. 每个消息实例包含销毁消息的方法
* 5. 每个消息实例包含消息ID
* 6. 每个消息实例包含消息内容
* 7. 每个消息实例包含消息类型
* 8. 每个消息实例包含消息持续时间设定
* ---
* Message组件被内嵌入ConfigProvider组件中,所以需要ConfigProvider组件先挂载
* 
*/
// 消息列表
const message = reactive<MessageInstance[]>([]);

// 使用消息组件
export const useNiMessage = () => {
    // 添加消息
    const addMessage = (options: MessageOptions) => {
        // 检测是否在NiConfigProvider组件中使用
        if (!defaultConfig.messageOnMounted) {
            throw new Error('useMessage must be used within NiConfigProvider!')
        };
        // 将时间戳作为消息ID
        const messageId = new Date().getTime() + Math.random();
        // 创建定时器，到时间消息自动销毁
        let timer: NodeJS.Timeout | null = null;
        // 定时器
        const startTimer = () => {
            clearTimer()
            timer = setTimeout(() => {
                const index = message.findIndex(item => item.messageId === messageId)
                message.splice(index, 1)
            }, options.duration || 3000);
        }
        // 销毁消息
        const destroy = () => {
            const index = message.findIndex(item => item.messageId === messageId)
            message.splice(index, 1)
        }
        // 清除定时器
        const clearTimer = () => {
            timer && clearTimeout(timer)
            timer = null;
        }
        // 执行初次定时器
        startTimer()
        // 添加消息
        message.unshift({
            ...options,
            messageId,
            timer,
            pause: clearTimer,
            resume: startTimer,
            destroy: () => {
                clearTimer()
                destroy()
            }
        })
    }
    return {
        message,
        show: addMessage,
        info: (content: string, option: MessageOptions) => addMessage({ ...option, content, type: 'info' }),
        success: (content: string, option: MessageOptions) => addMessage({ ...option, content, type: 'success' }),
        warning: (content: string, option: MessageOptions) => addMessage({ ...option, content, type: 'warning' }),
        error: (content: string, option: MessageOptions) => addMessage({ ...option, content, type: 'error' }),
    }
}

export default useNiMessage