"""
工作流协作API
支持多人实时协作编辑工作流
"""
from fastapi import APIRouter, WebSocket, WebSocketDisconnect, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session
from app.core.database import get_db, SessionLocal
from app.models.workflow import Workflow
from app.api.auth import get_current_user
from app.models.user import User
from app.websocket.collaboration_manager import collaboration_manager
from app.core.exceptions import NotFoundError
import json
import logging

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/api/v1/collaboration", tags=["collaboration"])


@router.websocket("/ws/workflows/{workflow_id}")
async def websocket_collaboration(
    websocket: WebSocket,
    workflow_id: str,
    token: str = None
):
    """
    工作流协作WebSocket连接
    
    支持多人实时协作编辑工作流，包括：
    - 节点添加/删除/移动
    - 边添加/删除
    - 节点配置修改
    - 实时同步变更
    
    参数:
    - token: JWT token（通过query参数传递，例如: ?token=xxx）
    """
    await websocket.accept()
    
    # 验证token
    if not token:
        await websocket.close(code=status.WS_1008_POLICY_VIOLATION, reason="缺少token")
        return
    
    db = SessionLocal()
    user = None
    
    try:
        # 验证JWT token
        from app.core.security import decode_access_token
        
        try:
            payload = decode_access_token(token)
            if payload is None:
                await websocket.close(code=status.WS_1008_POLICY_VIOLATION, reason="无效的token")
                return
            
            user_id_from_token = payload.get("sub")
            
            if not user_id_from_token:
                await websocket.close(code=status.WS_1008_POLICY_VIOLATION, reason="无效的token")
                return
            
            # 获取用户信息
            user = db.query(User).filter(User.id == user_id_from_token).first()
            if not user:
                await websocket.close(code=status.WS_1008_POLICY_VIOLATION, reason="用户不存在")
                return
            
        except Exception as e:
            logger.warning(f"Token验证失败: {e}")
            await websocket.close(code=status.WS_1008_POLICY_VIOLATION, reason="token验证失败")
            return
        
        # 获取工作流
        workflow = db.query(Workflow).filter(Workflow.id == workflow_id).first()
        if not workflow:
            await websocket.close(code=status.WS_1008_POLICY_VIOLATION, reason="工作流不存在")
            return
        
        # 检查权限（只有工作流所有者可以协作编辑，或者未来可以扩展权限）
        # 暂时只允许所有者编辑
        if workflow.user_id != user.id:
            await websocket.close(code=status.WS_1008_POLICY_VIOLATION, reason="无权限编辑此工作流")
            return
        
        user_id = user.id
        username = user.username
        
        # 建立协作连接
        await collaboration_manager.connect(websocket, workflow_id, user_id, username)
        
        try:
            # 持续监听消息
            while True:
                try:
                    # 接收客户端消息
                    data = await websocket.receive_text()
                    message = json.loads(data)
                    
                    message_type = message.get("type")
                    
                    if message_type == "ping":
                        # 心跳消息
                        await collaboration_manager.send_personal_message({
                            "type": "pong"
                        }, websocket)
                    
                    elif message_type == "operation":
                        # 工作流操作（节点/边的变更）
                        operation = message.get("operation", {})
                        op_type = operation.get("type")
                        
                        # 验证操作类型
                        valid_operations = [
                            "node_add", "node_delete", "node_move", "node_update",
                            "edge_add", "edge_delete", "edge_update",
                            "workflow_update"
                        ]
                        
                        if op_type not in valid_operations:
                            await collaboration_manager.send_personal_message({
                                "type": "error",
                                "message": f"无效的操作类型: {op_type}"
                            }, websocket)
                            continue
                        
                        # 添加操作者信息
                        operation["user_id"] = user_id
                        operation["username"] = username
                        
                        # 广播操作到其他用户
                        await collaboration_manager.broadcast_operation(
                            workflow_id,
                            operation,
                            exclude_websocket=websocket
                        )
                        
                        logger.info(f"用户 {username} 在工作流 {workflow_id} 执行操作: {op_type}")
                    
                    elif message_type == "cursor_move":
                        # 光标移动（可选功能）
                        cursor_info = message.get("cursor", {})
                        await collaboration_manager.broadcast_operation(
                            workflow_id,
                            {
                                "type": "cursor_move",
                                "user_id": user_id,
                                "username": username,
                                "cursor": cursor_info
                            },
                            exclude_websocket=websocket
                        )
                    
                    else:
                        await collaboration_manager.send_personal_message({
                            "type": "error",
                            "message": f"未知的消息类型: {message_type}"
                        }, websocket)
                
                except json.JSONDecodeError:
                    await collaboration_manager.send_personal_message({
                        "type": "error",
                        "message": "无效的JSON格式"
                    }, websocket)
        
        except WebSocketDisconnect:
            pass
        except Exception as e:
            logger.error(f"协作WebSocket错误: {e}", exc_info=True)
            try:
                await collaboration_manager.send_personal_message({
                    "type": "error",
                    "message": f"发生错误: {str(e)}"
                }, websocket)
            except:
                pass
        finally:
            collaboration_manager.disconnect(websocket, workflow_id)
            if db:
                db.close()
    
    except Exception as e:
        logger.error(f"建立协作连接失败: {e}", exc_info=True)
        try:
            await websocket.close()
        except:
            pass


@router.get("/workflows/{workflow_id}/users")
async def get_collaboration_users(
    workflow_id: str,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """获取当前协作编辑工作流的用户列表"""
    # 验证工作流存在
    workflow = db.query(Workflow).filter(Workflow.id == workflow_id).first()
    if not workflow:
        raise NotFoundError("工作流", workflow_id)
    
    # 获取在线用户
    online_users = collaboration_manager.get_online_users(workflow_id)
    
    return {
        "workflow_id": workflow_id,
        "online_users": online_users,
        "count": len(online_users)
    }
