from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import HTTPBearer
from sqlalchemy.orm import Session
from typing import Optional, Dict, Any
from datetime import datetime

from th_agenter.db.database import get_session
from th_agenter.services.auth import AuthService
from th_agenter.services.smart_workflow import SmartWorkflowManager
from th_agenter.services.conversation import ConversationService
from th_agenter.services.conversation_context import conversation_context_service
from utils.util_schemas import BaseResponse
from pydantic import BaseModel
from loguru import logger
from utils.util_exceptions import HxfResponse

router = APIRouter(prefix="/smart-chat", tags=["smart-chat"])
security = HTTPBearer()

# Request/Response Models
class SmartQueryRequest(BaseModel):
    query: str
    conversation_id: Optional[int] = None
    is_new_conversation: bool = False

class SmartQueryResponse(BaseModel):
    success: bool
    message: str
    data: Optional[Dict[str, Any]] = None
    workflow_steps: Optional[list] = None
    conversation_id: Optional[int] = None

class ConversationContextResponse(BaseModel):
    success: bool
    message: str
    data: Optional[Dict[str, Any]] = None

@router.post("/query", response_model=SmartQueryResponse, summary="智能问数查询")
async def smart_query(
    request: SmartQueryRequest,
    current_user = Depends(AuthService.get_current_user),
    session: Session = Depends(get_session)
):
    """
    智能问数查询接口
    支持新对话时自动加载文件列表，智能选择相关Excel文件，生成和执行pandas代码
    """
    session.desc = f"START: 用户 {current_user.username} 智能问数查询"
    conversation_id = None
    
    try:
        # 验证请求参数
        if not request.query or not request.query.strip():
            session.desc = "ERROR: 用户输入为空, 查询内容不能为空"
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="查询内容不能为空"
            )
        
        if len(request.query) > 1000:
            session.desc = "ERROR: 用户输入过长, 查询内容不能超过1000字符"
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="查询内容过长，请控制在1000字符以内"
            )
        
        # 初始化工作流管理器
        workflow_manager = SmartWorkflowManager(session)
        await workflow_manager.initialize()
        
        conversation_service = ConversationService(session)
        
        # 处理对话上下文
        conversation_id = request.conversation_id
        
        # 如果是新对话或没有指定对话ID，创建新对话
        if request.is_new_conversation or not conversation_id:
            try:
                conversation_id = await conversation_context_service.create_conversation(
                    user_id=current_user.id,
                    title=f"智能问数: {request.query[:20]}..."
                )
                request.is_new_conversation = True
                session.desc = f"创建新对话: {conversation_id}"
            except Exception as e:
                session.desc = f"WARNING: 创建对话失败，使用临时会话: {e}"
                conversation_id = None
        else:
            # 验证对话是否存在且属于当前用户
            try:
                context = await conversation_context_service.get_conversation_context(conversation_id)
                if not context or context.get('user_id') != current_user.id:
                    session.desc = f"ERROR: 对话 {conversation_id} 不存在或无权访问"
                    raise HTTPException(
                        status_code=status.HTTP_404_NOT_FOUND,
                        detail="对话不存在或无权访问"
                    )
                session.desc = f"使用现有对话: {conversation_id}"
            except HTTPException:
                session.desc = f"EXCEPTION: 对话 {conversation_id} 不存在或无权访问"
                raise
            except Exception as e:
                session.desc = f"ERROR: 验证对话失败: {e}"
                raise HTTPException(
                    status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                    detail="对话验证失败"
                )
        
        # 保存用户消息
        if conversation_id:
            try:
                await conversation_context_service.save_message(
                    conversation_id=conversation_id,
                    role="user",
                    content=request.query
                )
            except Exception as e:
                session.desc = f"WARNING: 保存用户消息失败: {e}"
                # 不阻断流程，继续执行查询
        
        # 执行智能查询工作流
        try:
            result = await workflow_manager.process_smart_query(
                user_query=request.query,
                user_id=current_user.id,
                conversation_id=conversation_id,
                is_new_conversation=request.is_new_conversation
            )
        except Exception as e:
            session.desc = f"ERROR: 智能查询执行失败: {e}"
            # 返回结构化的错误响应
            response = SmartQueryResponse(
                success=False,
                message=f"查询执行失败: {str(e)}",
                data={'error_type': 'query_execution_error'},
                workflow_steps=[{
                    'step': 'error',
                    'status': 'failed',
                    'message': str(e)
                }],
                conversation_id=conversation_id
            )
            return HxfResponse(response)
        
        # 如果查询成功，保存助手回复和更新上下文
        if result['success'] and conversation_id:
            try:
                # 保存助手回复
                await conversation_context_service.save_message(
                    conversation_id=conversation_id,
                    role="assistant",
                    content=result.get('data', {}).get('summary', '查询完成'),
                    metadata={
                        'query_result': result.get('data'),
                        'workflow_steps': result.get('workflow_steps', []),
                        'selected_files': result.get('data', {}).get('used_files', [])
                    }
                )
                
                # 更新对话上下文
                await conversation_context_service.update_conversation_context(
                    conversation_id=conversation_id,
                    query=request.query,
                    selected_files=result.get('data', {}).get('used_files', [])
                )
                
            except Exception as e:
                session.desc = f"EXCEPTION: 保存消息到对话历史失败: {e}"
                # 不影响返回结果，只记录警告
        
        # 返回结果，包含对话ID
        response_data = result.get('data', {})
        if conversation_id:
            response_data['conversation_id'] = conversation_id
        session.desc = f"SUCCESS: 保存助手回复和更新上下文，对话ID: {conversation_id}"
        response = SmartQueryResponse(
            success=result['success'],
            message=result.get('message', '查询完成'),
            data=response_data,
            workflow_steps=result.get('workflow_steps', []),
            conversation_id=conversation_id
        )
        return HxfResponse(response)
        
    except HTTPException as e:
        session.desc = f"EXCEPTION: HTTP异常: {e}"
        raise e
    except Exception as e:
        session.desc = f"ERROR: 智能查询接口异常: {e}"
        # 返回通用错误响应
        response = SmartQueryResponse(
            success=False,
            message="服务器内部错误，请稍后重试",
            data={'error_type': 'internal_server_error'},
            workflow_steps=[{
                'step': 'error',
                'status': 'failed',
                'message': '系统异常'
            }],
            conversation_id=conversation_id
        )
        return HxfResponse(response)

@router.get("/conversation/{conversation_id}/context", response_model=ConversationContextResponse, summary="获取对话上下文")
async def get_conversation_context(
    conversation_id: int,
    current_user = Depends(AuthService.get_current_user),
    session: Session = Depends(get_session)
):
    """
    获取对话上下文信息，包括已使用的文件和历史查询
    """
    # 获取对话上下文
    session.desc = f"START: 获取对话上下文，对话ID: {conversation_id}"
    context = await conversation_context_service.get_conversation_context(conversation_id)
    
    if not context:
        session.desc = f"ERROR: 对话上下文不存在，对话ID: {conversation_id}"
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="对话上下文不存在"
        )
    
    # 验证用户权限
    if context['user_id'] != current_user.id:
        session.desc = f"ERROR: 无权访问对话上下文，对话ID: {conversation_id}"
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="无权访问此对话"
        )
    
    # 获取对话历史
    history = await conversation_context_service.get_conversation_history(conversation_id)
    context['message_history'] = history
    session.desc = f"SUCCESS: 获取对话上下文成功，对话ID: {conversation_id}"
    response = ConversationContextResponse(
        success=True,
        message="获取对话上下文成功",
        data=context
    )
    return HxfResponse(response)
        

@router.get("/files/status", response_model=ConversationContextResponse, summary="获取用户当前的文件状态和统计信息")
async def get_files_status(
    current_user = Depends(AuthService.get_current_user),
    session: Session = Depends(get_session)
):
    """
    获取用户当前的文件状态和统计信息
    """
    session.desc = f"START: 获取用户文件状态和统计信息，用户ID: {current_user.id}"
    workflow_manager = SmartWorkflowManager()
    await workflow_manager.initialize()
    
    # 获取用户文件列表
    file_list = await workflow_manager.excel_workflow._load_user_file_list(current_user.id)
    
    # 统计信息
    total_files = len(file_list)
    total_rows = sum(f.get('row_count', 0) for f in file_list)
    total_columns = sum(f.get('column_count', 0) for f in file_list)
    
    # 文件类型统计
    file_types = {}
    for file_info in file_list:
        filename = file_info['filename']
        ext = filename.split('.')[-1].lower() if '.' in filename else 'unknown'
        file_types[ext] = file_types.get(ext, 0) + 1
    
    status_data = {
        'total_files': total_files,
        'total_rows': total_rows,
        'total_columns': total_columns,
        'file_types': file_types,
        'files': [{
            'id': f['id'],
            'filename': f['filename'],
            'row_count': f.get('row_count', 0),
            'column_count': f.get('column_count', 0),
            'columns': f.get('columns', []),
            'upload_time': f.get('upload_time')
        } for f in file_list],
        'ready_for_query': total_files > 0
    }
    
    session.desc = f"SUCCESS: 获取用户文件状态和统计信息成功，用户ID: {current_user.id}"
    response = ConversationContextResponse(
        success=True,
        message=f"当前有{total_files}个可用文件" if total_files > 0 else "暂无可用文件，请先上传Excel文件",
        data=status_data
    )
    return HxfResponse(response)

@router.post("/conversation/{conversation_id}/reset", summary="重置对话上下文")
async def reset_conversation_context(
    conversation_id: int,
    current_user = Depends(AuthService.get_current_user),
    session: Session = Depends(get_session)
):
    """
    重置对话上下文，清除历史查询记录但保留文件
    """
    session.desc = f"START: 重置对话上下文，对话ID: {conversation_id}"
    # 验证对话存在和用户权限
    context = await conversation_context_service.get_conversation_context(conversation_id)
    
    if not context:
        session.desc = f"ERROR: 对话上下文不存在，对话ID: {conversation_id}"
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="对话上下文不存在"
        )
    
    if context['user_id'] != current_user.id:
        session.desc = f"ERROR: 无权访问对话上下文，对话ID: {conversation_id}"
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="无权访问此对话"
        )
    
    # 重置对话上下文
    success = await conversation_context_service.reset_conversation_context(conversation_id)
    
    if success:
        session.desc = f"SUCCESS: 重置对话上下文成功，对话ID: {conversation_id}"
        response = ConversationContextResponse(
            success=True,
            message="对话上下文已重置，可以开始新的数据分析会话"
        )
        return HxfResponse(response)
    else:
        session.desc = f"EXCEPTION: 重置对话上下文失败，对话ID: {conversation_id}"
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="重置对话上下文失败"
        )
        