// 官方文档：https://docs.microsoft.com/zh-cn/aspnet/core/signalr/javascript-client?view=aspnetcore-6.0&viewFallbackFrom=aspnetcore-2.2&tabs=visual-studio
import * as signalR from '@microsoft/signalr';
import { Cookie } from '@/utils/storage';
import { submitLog } from '@/api/public/log';
import { getNowDateTime } from '@/utils/constants';
// 记录日志
const submitLogFn = async (request: any) => {
	try {
		await submitLog(request);
	} catch (error) {
		console.log(error);
	}
};
export default {
	// signalR对象
	SR: null as any,
	// 失败连接重试次数
	failNum: 99,
	baseUrl: import.meta.env.VITE_API_SOCKET_URL,
	init() {
		const token = Cookie.get('token');
		const connection = new signalR.HubConnectionBuilder()
			.withUrl(this.baseUrl, { accessTokenFactory: () => token, skipNegotiation: true, transport: 1 })
			.withAutomaticReconnect() //自动重新连接
			.configureLogging(signalR.LogLevel.Warning)
			.build();

		this.SR = connection;
		// 断线重连
		connection.onclose(async () => {
			const name: string = `业务系统的websocket断开链接`;
			const remark: string = `业务系统的websocket断开链接`;
			const request = {
				creationTime: new Date(),
				name,
				remark,
				executeUrl: import.meta.env.VITE_API_SOCKET_URL,
			};
			await submitLogFn(request);
			console.log(`${getNowDateTime()}：业务系统signal当前链接状态：${connection.state}`);
			// 建议用户重新刷新浏览器
			setTimeout(async () => {
				await this.start();
			}, 1000);
		});
		connection.onreconnected(async () => {
			const name: string = `业务系统websocket断线重连成功`;
			const remark: string = `业务系统websocket断线重连成功`;
			const request = {
				creationTime: new Date(),
				name,
				remark,
				executeUrl: import.meta.env.VITE_API_SOCKET_URL,
			};
			await submitLogFn(request);
			console.log(`${getNowDateTime()}：业务系统signal断线重连成功：${connection.state}`);
			// location.reload();
			/*ElNotification({
				type: 'success',
				title: '提示',
				message: `断线重连成功`,
			});*/
		});
		// 服务端推送消息
		connection.on('Send', (message: any) => {
			console.log(`${getNowDateTime()}：有用户加入分组：`, message);
		});
		// 服务端推送消息
		connection.on('CircularRecord', (message: any) => {
			console.log(`${getNowDateTime()}：小红点消息：`, message);
		});
		// 服务端推送消息
		connection.on('SeatState', (message: any) => {
			console.log(`${getNowDateTime()}：座席状态：`, message);
		});
		// 服务端推送消息
		connection.on('RestApplyPass', (message: any) => {
			console.log(`${getNowDateTime()}：休息申请通过：${message}`);
		});
		// 服务端推送消息
		connection.on('ToDayWaitNum', (message: any) => {
			// console.log(`今日等待：${message}`);
		});
		// 服务端推送消息
		connection.on('CurrentWaitNum', (message: any) => {
			// console.log(`当前等待：${message}`);
		});
		// 服务端推送消息
		connection.on('BsSeatStateDataShowArea1', (message: any) => {});
		// 服务端推送消息
		connection.on('BsSeatStateDataShowArea2', (message: any) => {});
		// 服务端推送消息
		connection.on('BsSeatStateDataShowArea3', (message: any) => {});
		// 服务端推送消息
		connection.on('BsSeatStateDataShowArea4', (message: any) => {});
	},
	/**
	 * @description 调用 this.signalR.start().then(async () => { await this.SR.invoke("method")})
	 * state  Connected 已连接  Connecting 正在连接  Disconnected 断开连接 Reconnecting 正在重新连接
	 * @returns
	 */
	async start() {
		return new Promise(async (resolve,reject)=>{
			try {
				//使用async和await 或 promise的then 和catch 处理来自服务端的异常
				await this.SR?.start();
				const name: string = `业务系统的websocket链接成功`;
				const remark: string = `业务系统的websocket链接成功`;
				const request = {
					creationTime: new Date(),
					name,
					remark,
					executeUrl: import.meta.env.VITE_API_SOCKET_URL,
				};
				await submitLogFn(request);
				console.log(`${getNowDateTime()}：业务系统signal当前链接状态：${this.SR.state}`);
				return resolve(true);
			} catch (error: any) {
				this.failNum--;
				if (this.failNum > 0 && this.SR?.state === 'Disconnected') {
					//断开链接重新链接
					/*ElNotification({
						type: 'warning',
						title: '提示',
						message: `断开连接了,正在重连, 剩余自动重连次数${this.failNum} 次，如未重连成功，请刷新浏览器重试`,
					});*/
					setTimeout(async () => {
						await this.SR?.start();
					}, 5000);
				}
				return reject(error);
			}
		})
	},
	/**
	 * @description 加入分组
	 * @param groupName string 分组名称
	 * @params {string} CallCenter 呼叫中心
	 * @params BigScreenDataShow 大屏数据展示
	 * @returns
	 */
	async joinGroup(groupName: string) {
		if (this.SR?.state === 'Connected') {
			// 判断是否已经建立链接 如果没有 先链接
			await this.SR.invoke('JoinGroupAsync', { GroupName: groupName });
		} else {
			try {
				this.start().then(()=>{
					this.SR?.invoke('JoinGroupAsync', { GroupName: groupName });
				})
			} catch (err) {
				console.log(err);
			}
		}
	},
	/**
	 * @description 离开分组
	 * @param groupName string
	 * @params CallCenter 呼叫中心
	 * @params BigScreenDataShow 大屏数据展示
	 * @returns
	 */
	async leaveGroup(groupName: string) {
		if (this.SR.state === 'Connected') {
			// 判断是否已经建立链接 如果没有 先链接
			await this.SR.invoke('LeaveGroupAsync', { GroupName: groupName });
		} else {
			// 等待链接成功再发送
			if (this.SR.state === 'Connecting') {
				setTimeout(async () => {
					await this.SR.invoke('LeaveGroupAsync', { GroupName: groupName });
				}, 500);
				return;
			}
			this.start()
				.then(() => {
					this.SR.invoke('LeaveGroupAsync', { GroupName: groupName });
				})
				.catch((err) => {
					console.log(err);
				});
		}
	},

	/**
	 * @description 关闭链接
	 * @returns
	 */
	async stop() {
		try {
			//使用async和await 或 promise的then 和catch 处理来自服务端的异常
			await this.SR.stop();
			console.log(`${getNowDateTime()}：业务系统链接关闭：${this.SR.state}`);
		} catch (error) {
			console.log('signalR', error);
		}
	},
	/**
	 * @description 离开所有分组并且关闭链接
	 * @returns
	 */
	async leaveAllGroupAndStop() {
		return new Promise(async (resolve, reject) => {
			try {
				//使用async和await 或 promise的then 和catch 处理来自服务端的异常
				await this.leaveGroup('CallCenter');
				await this.leaveGroup('BigScreen-SeatState');
				await this.stop();
				console.log(`${getNowDateTime()}：断开链接：${this.SR.state}`);
				return resolve(true);
			} catch (error) {
				console.log('signalR', error);
				return reject(error);
			}
		});
	},
};
