import { ref } from 'vue';
import { io, Socket } from 'socket.io-client';
import { host as backendHost } from '/@/config/proxy';
import type { WSClientMessage, WSServerEvent } from '../types/index.d';

// 扩展客户端消息类型，支持设置思考级别
type ExtendedWSClientMessage = WSClientMessage & { type: WSClientMessage['type'] | 'set_thinking_level' };

/**
 * NetaClaw WebSocket 连接管理（Socket.IO 客户端）
 * 后端使用 @midwayjs/socketio，必须用 socket.io-client 直连后端
 * 注意：不能走 Vite 代理（/dev），Socket.IO 需要直连后端地址
 */
export function useNetaClawWS() {
	const connected = ref(false);
	let socket: Socket | null = null;
	const handlers = new Set<(event: WSServerEvent) => void>();

	function getBackendUrl(): string {
		// 开发环境直连后端；生产环境用当前域名（反向代理处理 WS）
		if (backendHost) return backendHost;
		return window.location.origin;
	}

	function connect() {
		if (socket?.connected) return;
		if (socket) {
			socket.removeAllListeners();
			socket.disconnect();
			socket = null;
		}

		const url = `${getBackendUrl()}/netaclaw`;
		console.log('[NetaClaw WS] 正在连接:', url);

		// 直连后端 Socket.IO /netaclaw namespace
		socket = io(url, {
			transports: ['websocket', 'polling'],
		});

		socket.on('connect', () => {
			connected.value = true;
			console.log('[NetaClaw WS] 已连接, id:', socket?.id);
		});

		socket.on('message', (data: string) => {
			let event: WSServerEvent;
			try {
				event = JSON.parse(data);
			} catch {
				console.warn('[NetaClaw WS] 无法解析消息:', data);
				return;
			}
			handlers.forEach(h => {
				try { h(event); } catch (e) {
					console.error('[NetaClaw WS] 事件处理异常:', event.type, e);
				}
			});
		});

		socket.on('disconnect', (reason: string) => {
			connected.value = false;
			console.log('[NetaClaw WS] 已断开:', reason);
		});

		socket.on('connect_error', (err: Error) => {
			console.error('[NetaClaw WS] 连接错误:', err.message);
		});
	}

	function send(msg: ExtendedWSClientMessage) {
		if (socket?.connected) {
			socket.emit('message', JSON.stringify(msg));
		} else {
			// 连接中，等连上后自动发送
			console.log('[NetaClaw WS] 等待连接后发送:', msg.type);
			const onceConnect = () => {
				socket?.emit('message', JSON.stringify(msg));
			};
			socket?.once('connect', onceConnect);
			// 5秒超时
			setTimeout(() => {
				socket?.off('connect', onceConnect);
			}, 5000);
		}
	}

	function onEvent(handler: (event: WSServerEvent) => void) {
		handlers.add(handler);
		return () => { handlers.delete(handler); };
	}

	function disconnect() {
		if (socket) {
			socket.removeAllListeners();
			socket.disconnect();
			socket = null;
		}
		connected.value = false;
	}

	return { connected, connect, disconnect, send, onEvent };
}
