from fastapi import APIRouter, Depends, HTTPException, status, Request
from sqlalchemy.orm import Session
from datetime import datetime, timedelta

from app.core.database import get_db
from app.core.security import verify_token
from app.core.token_blacklist import token_blacklist
from app.services.user_service import UserService
from app.schemas.auth import (
    UserRegister, UserLogin, UserResponse, LoginResponse,
    TokenResponse, TokenRefresh, ApiResponse
)
from app.dependencies.auth import get_current_user_response
from app.models.user import User
from app.exceptions.auth import UsernameAlreadyExistsException

router = APIRouter()

@router.post("/register", status_code=status.HTTP_201_CREATED)
async def register(request: Request, user_data: UserRegister, db: Session = Depends(get_db)):
    """用户注册"""
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    print(f"[{timestamp}] INFO: === 注册接口 ===")
    print(f"[{timestamp}] INFO: 用户名: {user_data.username}")
    print(f"[{timestamp}] INFO: 邮箱: {user_data.email}")
    print(f"[{timestamp}] INFO: 密码长度: {len(user_data.password)}字符")
    print(f"[{timestamp}] INFO: 确认密码长度: {len(user_data.confirm_password)}字符")
    print(f"[{timestamp}] DEBUG: Starting registration process...")

    try:
        user_service = UserService(db)

        # 创建用户
        print("[DEBUG] Creating user...")
        user = user_service.create_user(user_data)
        print(f"[DEBUG] User created successfully with ID: {user.id}")

        # 创建令牌
        print("[DEBUG] Creating tokens...")
        tokens = user_service.create_user_tokens(user)
        print("[DEBUG] Tokens created successfully")

        # 转换为响应格式
        print("[DEBUG] Converting to response format...")
        user_response = user_service.to_user_response(user)
        print("[DEBUG] Response conversion successful")

        response_data = {
            "user": user_response.dict(),
            "tokens": tokens
        }
        print("[DEBUG] Response data created successfully")

        return ApiResponse(
            success=True,
            message="注册成功",
            data=response_data
        )

    except UsernameAlreadyExistsException as e:
        print(f"[DEBUG] UsernameAlreadyExistsException caught: {e}")
        raise e
    except HTTPException as e:
        print(f"[DEBUG] HTTPException caught: {e}")
        raise e
    except Exception as e:
        # 打印异常信息以便调试
        import traceback
        print(f"[ERROR] Unexpected error in register: {e}")
        print(f"[ERROR] Exception type: {type(e)}")
        traceback.print_exc()

        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail={
                "code": "REGISTRATION_FAILED",
                "message": f"注册过程中发生错误: {str(e)}"
            }
        )

@router.post("/login", response_model=ApiResponse)
async def login(request: Request, login_data: UserLogin, db: Session = Depends(get_db)):
    """用户登录"""
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    print(f"[{timestamp}] INFO: === 登录接口 ===")
    print(f"[{timestamp}] INFO: 用户名: {login_data.username}")
    print(f"[{timestamp}] INFO: 密码长度: {len(login_data.password)}字符")
    print(f"[{timestamp}] DEBUG: Starting authentication process...")

    try:
        user_service = UserService(db)
        # 验证用户
        user = user_service.authenticate_user(login_data)
        if not user:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail={
                    "code": "INVALID_CREDENTIALS",
                    "message": "用户名或密码错误"
                }
            )

        # 创建令牌
        tokens = user_service.create_user_tokens(user)

        # 转换为响应格式
        user_response = user_service.to_user_response(user)

        return ApiResponse(
            success=True,
            message="登录成功",
            data={
                "user": user_response.dict(),
                "tokens": tokens
            }
        )

    except HTTPException as e:
        raise e
    except Exception as e:
        print("用户登录的异常:",e)
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail={
                "code": "LOGIN_FAILED",
                "message": "登录过程中发生错误"
            }
        )

@router.post("/refresh", response_model=ApiResponse)
async def refresh_token(token_data: TokenRefresh, db: Session = Depends(get_db)):
    """刷新访问令牌"""
    try:
        # 验证刷新令牌
        payload = verify_token(token_data.refresh_token, "refresh")
        if not payload:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail={
                    "code": "INVALID_REFRESH_TOKEN",
                    "message": "无效的刷新令牌"
                }
            )

        # 获取用户ID
        user_id = int(payload.get("sub"))
        user_service = UserService(db)
        user = user_service.get_user_by_id(user_id)

        if not user:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail={
                    "code": "USER_NOT_FOUND",
                    "message": "用户不存在"
                }
            )

        # 创建新的访问令牌
        tokens = user_service.create_user_tokens(user)

        return ApiResponse(
            success=True,
            message="令牌刷新成功",
            data={
                "tokens": tokens
            }
        )

    except HTTPException as e:
        raise e
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail={
                "code": "TOKEN_REFRESH_FAILED",
                "message": "令牌刷新过程中发生错误"
            }
        )

@router.get("/me", response_model=ApiResponse)
async def get_current_user_info(current_user: UserResponse = Depends(get_current_user_response)):
    """获取当前用户信息"""
    return ApiResponse(
        success=True,
        message="获取用户信息成功",
        data={
            "user": current_user.dict()
        }
    )

@router.post("/logout", response_model=ApiResponse)
async def logout(
    request: Request,
    current_user: UserResponse = Depends(get_current_user_response)
):
    """用户登出"""
    try:
        # 从请求头中获取Authorization令牌
        authorization = request.headers.get("Authorization")
        if authorization and authorization.startswith("Bearer "):
            token = authorization.split(" ")[1]
            # 将令牌加入黑名单
            token_blacklist.add_token(token)

        return ApiResponse(
            success=True,
            message="登出成功",
            data={}
        )
    except Exception as e:
        # 即使添加令牌到黑名单失败，也返回成功，因为登出操作主要目的是让客户端删除令牌
        return ApiResponse(
            success=True,
            message="登出成功",
            data={}
        )