"""
Admin API - Users Routes

包含用户管理相关的 API 路由。
"""

import logging
from typing import Optional

from fastapi import APIRouter, Depends, Query, Request

from src.auth.dependencies import require_admin
from src.auth.models import UserAuth
from src.models.schemas import ResponseModel, PaginationParams
from src.models.admin_schemas import (
    AdminUserCreateRequest,
    AdminUserUpdateRequest,
)
from src.services.admin_service import admin_service
from src.services.user_service import user_service
from src.utils.pagination import Paginator
from src.utils.errors import ErrorCode, AppException

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/users", tags=["admin-users"])


@router.get("", response_model=ResponseModel)
async def list_users(
    request: Request,
    page: int = Query(1, ge=1, description="Page number, starting from 1"),
    page_size: int = Query(20, ge=1, le=100, description="Items per page"),
    sort: Optional[str] = Query(None, description="Sort field, format: field:asc or field:desc"),
    filter: Optional[str] = Query(None, description="Filter conditions, JSON format"),
    current_user: UserAuth = Depends(require_admin),
) -> ResponseModel:
    """
    List all users with pagination

    Supports filtering by is_active, is_superuser, and search by username/email.
    Requires admin privileges.
    """
    try:
        # Parse filters
        filters = {}
        if filter:
            import json
            try:
                filters = json.loads(filter)
            except json.JSONDecodeError:
                pass

        # Parse sort
        sort_by = "created_at"
        sort_order = "desc"
        if sort:
            parts = sort.split(":")
            if len(parts) == 2:
                sort_by = parts[0]
                sort_order = parts[1]

        items, total = await admin_service.list_users(
            page=page,
            page_size=page_size,
            filters=filters if filters else None,
            sort_by=sort_by,
            sort_order=sort_order,
        )

        paginator = Paginator(
            items=[item.model_dump() for item in items],
            total=total,
            page=page,
            page_size=page_size,
        )

        return paginator.to_response(request)
    except Exception as e:
        logger.error(f"Error listing users: {e}")
        raise AppException(
            code=ErrorCode.INTERNAL_ERROR,
            message=str(e),
            status_code=500
        )


@router.get("/{user_id}", response_model=ResponseModel)
async def get_user(
    user_id: str,
    current_user: UserAuth = Depends(require_admin),
) -> ResponseModel:
    """
    Get user details by ID

    Requires admin privileges.
    """
    try:
        user = await admin_service.get_user(user_id)
        if not user:
            raise AppException(
                code=ErrorCode.NOT_FOUND,
                message="User not found",
                status_code=404
            )
        return ResponseModel(data=user.model_dump())
    except AppException:
        raise
    except Exception as e:
        logger.error(f"Error getting user: {e}")
        raise AppException(
            code=ErrorCode.INTERNAL_ERROR,
            message=str(e),
            status_code=500
        )


@router.post("", response_model=ResponseModel)
async def create_user(
    request: AdminUserCreateRequest,
    current_user: UserAuth = Depends(require_admin),
) -> ResponseModel:
    """
    Create a new user

    Requires admin privileges.
    """
    try:
        # Check if username already exists
        existing_user = await user_service.get_user_by_username(request.username)
        if existing_user:
            raise AppException(
                code=ErrorCode.CONFLICT,
                message="Username already exists",
                status_code=400
            )

        # Check if email already exists
        existing_email = await user_service.get_user_by_email(request.email)
        if existing_email:
            raise AppException(
                code=ErrorCode.CONFLICT,
                message="Email already registered",
                status_code=400
            )

        # Create user using user_service
        user = await user_service.create_user(
            username=request.username,
            email=request.email,
            password=request.password
        )

        # Update additional fields if provided
        update_data = {}
        if request.is_active is not None:
            update_data["is_active"] = request.is_active
        if request.is_superuser is not None:
            update_data["is_superuser"] = request.is_superuser
        if request.roles:
            update_data["roles"] = request.roles
        if request.permissions:
            update_data["permissions"] = request.permissions

        if update_data:
            user = await admin_service.update_user(user.id, update_data)

        logger.info(f"Admin {current_user.username} created user: {user.username} ({user.id})")

        return ResponseModel(
            data=user.model_dump(),
            message="User created successfully"
        )
    except AppException:
        raise
    except Exception as e:
        logger.error(f"Error creating user: {e}")
        raise AppException(
            code=ErrorCode.INTERNAL_ERROR,
            message=str(e),
            status_code=500
        )


@router.put("/{user_id}", response_model=ResponseModel)
async def update_user(
    user_id: str,
    request: AdminUserUpdateRequest,
    current_user: UserAuth = Depends(require_admin),
) -> ResponseModel:
    """
    Update user information

    Requires admin privileges.
    """
    try:
        # Prevent self-demotion from superuser
        if user_id == current_user.id and request.is_superuser is False:
            raise AppException(
                code=ErrorCode.FORBIDDEN,
                message="Cannot remove your own superuser status",
                status_code=400
            )

        update_data = request.model_dump(exclude_unset=True)
        user = await admin_service.update_user(user_id, update_data)

        if not user:
            raise AppException(
                code=ErrorCode.NOT_FOUND,
                message="User not found",
                status_code=404
            )

        return ResponseModel(data=user.model_dump())
    except AppException:
        raise
    except Exception as e:
        logger.error(f"Error updating user: {e}")
        raise AppException(
            code=ErrorCode.INTERNAL_ERROR,
            message=str(e),
            status_code=500
        )


@router.post("/{user_id}/toggle-active", response_model=ResponseModel)
async def toggle_user_active(
    user_id: str,
    current_user: UserAuth = Depends(require_admin),
) -> ResponseModel:
    """
    Toggle user active status

    Requires admin privileges.
    """
    try:
        # Prevent self-deactivation
        if user_id == current_user.id:
            raise AppException(
                code=ErrorCode.FORBIDDEN,
                message="Cannot deactivate your own account",
                status_code=400
            )

        user = await admin_service.get_user(user_id)
        if not user:
            raise AppException(
                code=ErrorCode.NOT_FOUND,
                message="User not found",
                status_code=404
            )

        new_status = not user.is_active
        updated_user = await admin_service.toggle_user_active(user_id, new_status)

        return ResponseModel(
            data={
                "id": user_id,
                "is_active": new_status,
                "message": f"User {'activated' if new_status else 'deactivated'} successfully",
            }
        )
    except AppException:
        raise
    except Exception as e:
        logger.error(f"Error toggling user active status: {e}")
        raise AppException(
            code=ErrorCode.INTERNAL_ERROR,
            message=str(e),
            status_code=500
        )


@router.delete("/{user_id}", response_model=ResponseModel)
async def delete_user(
    user_id: str,
    current_user: UserAuth = Depends(require_admin),
) -> ResponseModel:
    """
    Delete a user

    Requires admin privileges.
    """
    try:
        # Prevent self-deletion
        if user_id == current_user.id:
            raise AppException(
                code=ErrorCode.FORBIDDEN,
                message="Cannot delete your own account",
                status_code=400
            )

        success = await admin_service.delete_user(user_id)
        if not success:
            raise AppException(
                code=ErrorCode.NOT_FOUND,
                message="User not found",
                status_code=404
            )

        return ResponseModel(
            data={
                "id": user_id,
                "deleted": True,
                "message": "User deleted successfully",
            }
        )
    except AppException:
        raise
    except Exception as e:
        logger.error(f"Error deleting user: {e}")
        raise AppException(
            code=ErrorCode.INTERNAL_ERROR,
            message=str(e),
            status_code=500
        )
