"""
WebSocket服务器主入口

实现2.1和2.3接口：
- 2.1: 异常状态触发对话 (abnormal_trigger)
- 2.3: 双向音频流对话 (audio_stream)

启动方式：
    python src/MainServices.py
    或
    python -m src.MainServices

WebSocket服务器地址：ws://0.0.0.0:8765
"""

import asyncio
import json
import sys
from pathlib import Path

import websockets

# 添加项目根目录到Python路径
project_root = Path(__file__).parent.parent
if str(project_root) not in sys.path:
    sys.path.insert(0, str(project_root))

from src.handlers.abnormal_trigger import handle_abnormal_trigger
from src.handlers.audio_stream import AudioStreamHandler


class WebSocketServer:
    """WebSocket服务器 - 处理2.1和2.3接口"""

    def __init__(self, host: str = "0.0.0.0", port: int = 8765):
        """
        初始化WebSocket服务器

        Args:
            host: 监听地址
            port: 监听端口
        """
        self.host = host
        self.port = port
        self.sessions = {}  # session_id -> AudioStreamHandler 映射

    async def handler(self, websocket):
        """
        WebSocket连接处理器

        根据消息type路由到不同处理器

        Args:
            websocket: WebSocket连接
        """
        remote_addr = websocket.remote_address
        print(f"[WS] 新连接: {remote_addr}")

        try:
            async for message in websocket:
                try:
                    data = json.loads(message)
                    msg_type = data.get("type")

                    # 路由消息到不同处理器
                    if msg_type == "abnormal_trigger":
                        # 2.1: 异常状态触发对话
                        print(f"[路由] abnormal_trigger 请求")
                        await handle_abnormal_trigger(websocket, data)

                    elif msg_type == "audio_stream_init":
                        # 2.3: 音频流初始化握手
                        session_id = data.get("session_id")
                        print(f"[路由] audio_stream_init 请求，session_id={session_id}")
                        handler = AudioStreamHandler(websocket, data)
                        self.sessions[session_id] = handler
                        await handler.init_response()

                    elif msg_type == "audio_stream_upload":
                        # 2.3: 音频流上传
                        session_id = data.get("session_id")
                        handler = self.sessions.get(session_id)
                        if handler:
                            await handler.handle_audio_upload(data)
                        else:
                            await websocket.send(json.dumps({
                                "type": "error",
                                "message": f"会话不存在: {session_id}"
                            }))

                    elif msg_type == "audio_stream_control":
                        # 2.3: 控制消息
                        session_id = data.get("session_id")
                        handler = self.sessions.get(session_id)
                        if handler:
                            await handler.handle_control(data)
                        else:
                            await websocket.send(json.dumps({
                                "type": "error",
                                "message": f"会话不存在: {session_id}"
                            }))

                    else:
                        print(f"[未知消息类型] {msg_type}")
                        await websocket.send(json.dumps({
                            "type": "error",
                            "message": f"未知消息类型: {msg_type}"
                        }))

                except json.JSONDecodeError:
                    print("[JSON解析错误]")
                    await websocket.send(json.dumps({
                        "type": "error",
                        "message": "JSON解析失败"
                    }))
                except Exception as e:
                    print(f"[处理错误] {e}")
                    try:
                        await websocket.send(json.dumps({
                            "type": "error",
                            "message": str(e)
                        }))
                    except Exception:
                        pass

        except websockets.exceptions.ConnectionClosed:
            print(f"[WS] 连接关闭: {remote_addr}")

        finally:
            # 清理session
            to_remove = [
                sid for sid, h in self.sessions.items()
                if h.websocket == websocket
            ]
            for sid in to_remove:
                print(f"[清理] 删除session: {sid}")
                del self.sessions[sid]

    async def start(self):
        """启动WebSocket服务器"""
        print(f"\n{'='*60}")
        print(f"[WS] WebSocket服务器启动")
        print(f"[WS] 监听地址: ws://{self.host}:{self.port}")
        print(f"[WS] 接口:")
        print(f"     - 2.1 异常状态触发对话 (abnormal_trigger)")
        print(f"     - 2.3 双向音频流对话 (audio_stream_*)")
        print(f"{'='*60}\n")

        # websockets 15.0+ 兼容处理
        try:
            # 新版本API
            async with websockets.serve(self.handler, self.host, self.port):
                await asyncio.Future()  # 永久运行
        except TypeError:
            # 旧版本兼容
            async with websockets.serve(self.handler, self.host, self.port):
                await asyncio.Future()


def main():
    """主函数"""
    server = WebSocketServer(host="0.0.0.0", port=8765)

    try:
        asyncio.run(server.start())
    except KeyboardInterrupt:
        print("\n\n[WS] 服务器关闭")


if __name__ == "__main__":
    main()
