"""
User router for handling user-related API endpoints.
"""

from typing import List, Optional, Dict, Union, Any
from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session
from pydantic.networks import EmailStr

from src.core.database import get_db
from src.apps.auth.utils.auth import get_current_active_user, get_current_superuser
from src.apps.users.models.user import User
from src.apps.users import services
from src.apps.users.schemas.user_common import UserResponseSchema, UserCreateSchema, UserUpdateSchema

router = APIRouter()


@router.post("/", response_model=UserResponseSchema, status_code=status.HTTP_201_CREATED)
def create_user(
    *,
    db: Session = Depends(get_db),
    user_in: UserCreateSchema,
    current_user: User = Depends(get_current_superuser),  # Only superusers can create users
) -> Any:
    """
    Create new user (Admin only).
    """
    # Check if user with this email already exists
    existing_user = services.get_user_by_email(db, email=user_in.email)
    if existing_user:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="User with this email already exists"
        )
    
    # Create user using services
    user, message = services.create_user(db, user_data=user_in)
    if user is None:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=message
        )
    
    return user


@router.get("/", response_model=Dict[str, Any])
def get_users_list(
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user),  # Require authentication
    page: int = Query(1, ge=1, description="Page number"),
    per_page: int = Query(20, ge=1, le=100, description="Items per page"),
    search: Optional[str] = Query(None, description="Search across name, email, phone"),
    name: Optional[str] = Query(None, description="Search by name"),
    email: Optional[str] = Query(None, description="Filter by email"),
    phone: Optional[str] = Query(None, description="Filter by phone"),
    is_active: int = Query(0, description="Filter by active status (0=all, 1=active, -1=inactive)"),
    is_verified: int = Query(0, description="Filter by verified status (0=all, 1=verified, -1=unverified)"),
    sort_by: List[str] = Query(["-created_at"], description="Sort fields (prefix with - for desc)"),
) -> Any:
    """
    Retrieve users with filtering and pagination (Authenticated users only).
    """
    # Calculate offset from page
    skip = (page - 1) * per_page
    
    # Get users using services
    result = services.get_users_list(
        db=db,
        search=search,
        name=name,
        email=email,
        phone=phone,
        is_active=is_active,
        is_verified=is_verified,
        sort_by=sort_by,
        skip=skip,
        limit=per_page,
        paginate=True,
    )
    
    return result


@router.get("/{user_id}", response_model=UserResponseSchema)
def get_user(
    user_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user),  # Require authentication
) -> Any:
    """
    Get user by ID (Authenticated users only).
    
    Users can only access their own profile unless they are superusers.
    """
    # Check if user is trying to access their own profile or is a superuser
    if current_user.id != user_id and not current_user.is_superuser:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions to access this user"
        )
    
    result = services.get_user(db, user_id=user_id)
    if not result or result[0] is None:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="User not found"
        )
    
    user_schema, message = result
    return user_schema


@router.put("/{user_id}", response_model=UserResponseSchema)
def update_user(
    *,
    db: Session = Depends(get_db),
    user_id: int,
    user_in: UserUpdateSchema,
    current_user: User = Depends(get_current_active_user),  # Require authentication
) -> Any:
    """
    Update user (Users can only update their own profile unless they are superusers).
    """
    # Check if user is trying to update their own profile or is a superuser
    if current_user.id != user_id and not current_user.is_superuser:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions to update this user"
        )
    
    # Check if user exists
    existing_user = services.get_user(db, user_id=user_id)
    if not existing_user or existing_user[0] is None:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="User not found"
        )
    
    # Check if email is being changed and if it's already taken
    if user_in.email:
        email_user = services.get_user_by_email(db, email=user_in.email)
        if email_user and email_user.id != user_id:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="User with this email already exists"
            )
    
    # Update user using services
    updated_user = services.update_user(db, user_id=user_id, user_data=user_in)
    if updated_user is None:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Failed to update user"
        )
    
    return updated_user


@router.delete("/{user_id}", response_model=UserResponseSchema)
def delete_user(
    user_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_superuser),  # Only superusers can delete users
) -> Any:
    """
    Delete user (Admin only - soft delete if supported).
    """
    # Try soft delete first
    soft_delete_result = services.soft_delete_user(db, user_id=user_id)
    if soft_delete_result and soft_delete_result.get("deleted"):
        # Get user data before returning
        user_result = services.get_user(db, user_id=user_id)
        if user_result and user_result[0]:
            return user_result[0]
    
    # Fallback to hard delete
    deleted_user = services.delete_user(db, user_id=user_id)
    if deleted_user is None:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="User not found"
        )
    
    return deleted_user



