import { defineStore } from "pinia";
import { Toast, format, setStorage, getStorage } from '@/utils';
import { RONGIMCALL_OPEN, RONGIMCALL_CLOSE, RONGIMCALL_HISTORY, RONGIMCALL_SEND } from '@/api';
import { useSocketStore } from "@/store";


export const useMessageStore = defineStore("chat_message", {
	state: () => ({
		globalMap: {
			serviceChannel: {
				type: 'service',
				unreadCount: 0,
				lastTime: getStorage('serviceChannel') ? getStorage('serviceChannel') : ''
			},
			noticeChannel: {
				type: 'notice',
				unreadCount: 0,
				lastTime: getStorage('noticeChannel') ? getStorage('noticeChannel') : ''
			}
		},
		messageMap: {},
		userSessionChannel: ''
	}),

	getters: {
		userSessionChannelInfo() {
			if (!this.userSessionChannel) return null;
			return this.messageMap[this.userSessionChannel];
		},
	},

	actions: {
		initMessageMap(key, data = {}) {
			if (!key) return;
			this.messageMap[key] = {
				messageList: [],
				unreadCount: 0,
				openInfo: {
					...data
				}
			}
		},

		updateStatus(key, state) {

			if (!key || !(state >= 0)) return;
			if (!this.messageMap[key]) return;
			this.messageMap[key].openInfo.status = state;
		},

		/**
		 * @description 更新未读数量
		 * @param {Number} count  为 -1 时重置未读数量
		 */
		updateUnreadCount(key, count = 1) {
			if (!key) return;
			if (!this.messageMap[key]) return;
			if (count > 0) {
				this.messageMap[key].unreadCount += count
			}
			else if (count == -1) {
				this.messageMap[key].unreadCount = 0
			}
		},

		updateGlobalMapUnreadCount(key, count = 1) {
			if (!key) return;
			if (!this.globalMap[key]) return;
			if (count > 0) {
				this.globalMap[key].unreadCount += count
			}
			else if (count == -1) {
				this.globalMap[key].unreadCount = 0
			}
			this.getTotalUnreadCount()
		},

		updateGlobalMapLasttime(key, timestamp) {
			if (!key) return;
			if (!this.globalMap[key]) return;
			if (timestamp >= 0) {
				this.globalMap[key].lastTime = timestamp
				setStorage(key, timestamp)
			}
			else if (count == -1) {
				this.globalMap[key].lastTime = 0
			}
		},
		/**
	 * @description 将 globalMap 中所有渠道的未读数量重置为 0
	 */
		resetAllGlobalUnreadCount() {
			Object.keys(this.globalMap).forEach(key => {
				if (this.globalMap[key] && typeof this.globalMap[key].unreadCount === 'number') {
					this.globalMap[key].unreadCount = 0; // 重置为 0
				}
			});
			this.getTotalUnreadCount();
		},

		getTotalUnreadCount() {
			let total = 0;
			for (const key in this.globalMap) {
				if (this.globalMap[key].unreadCount) {
					total += this.globalMap[key].unreadCount;
				}
			}
			// #ifdef APP-PLUS
			plus.runtime.setBadgeNumber(total);
			// #endif
			return total;
		},

		/**
		 * @description 更新消息列表
		 * @param {string} key
		 * @param {string} type 'push' | 'unshift'
		 */
		updateMessageList(key, data, type = 'unshift') {
			if (!key || !data) return;
			if (!this.messageMap[key]) return;
			if (type == 'push') {
				this.messageMap[key].messageList.push(data)
			}
			else {
				this.messageMap[key].messageList.unshift(data)
			}
		},

		openChannel(query = {}) {
			return new Promise((resolve, reject) => {
				RONGIMCALL_OPEN(query).then(result => {
					const { data } = result;
					this.userSessionChannel = data.auth.channel;
					this.initMessageMap(data.auth.channel, data);
					const useScoket = useSocketStore();
					useScoket.send({
						event: "pusher:subscribe",
						data: data.auth
					})
					resolve(result);
				})
					.catch(err => {
						Toast(err.msg);
						reject(err);
					})
			})
		},

		closeChannel(query = {}) {
			return new Promise((resolve, reject) => {
				RONGIMCALL_CLOSE(query).then(result => {
					const { data } = result;
					resolve(result);
				})
					.catch(err => {
						Toast(err.msg);
						reject(err);
					})
			})
		},

		sendMessage(data, type = 'service', other = {}) {
			return new Promise(async (resolve, reject) => {
				try {
					const result = await RONGIMCALL_SEND({
						type: type,
						msg: JSON.stringify(data),
						...other
					});
					resolve(result.data);
				}
				catch (err) {
					Toast(err.msg);
					reject(err);
				}
			})
		}
	}
})