from fastapi import Depends

from beanie import PydanticObjectId

from fastapi import APIRouter, HTTPException
from typing import List

from .models import User
from .schemas import UserRead, UserUpdate, UserCreate
from .manager import get_user_manager, get_current_user, get_current_superuser


router = APIRouter()


@router.post("/", response_description="User added to the database")
async def create(user_form: UserCreate, user_manager=Depends(get_user_manager), user=Depends(get_current_superuser)) -> dict:
    await user_manager.create(user_form, safe=True)
    return {"message": "User added successfully"}


@router.get("/me", response_description="User record retrieved")
async def read_me(user=Depends(get_current_user)) -> UserRead:
    user = await User.get(user.id)
    return UserRead(**user.dict())


@router.get("/{id}", response_description="User record retrieved")
async def read_id(id: PydanticObjectId, user=Depends(get_current_superuser)) -> UserRead:
    user = await User.get(id)
    return UserRead(**user.dict())


@router.get("/", response_model=List[UserRead], response_description="User records retrieved")
async def read_list(user=Depends(get_current_superuser)) -> List[UserRead]:
    users = await User.find_all().to_list()
    return users


@router.put("/{id}", response_description="User record updated")
async def update(id: PydanticObjectId, user_form: UserUpdate, user=Depends(get_current_superuser)) -> UserRead:
    user_form = {k: v for k, v in user_form.dict().items() if v is not None}
    update_query = {"$set": {
        field: value for field, value in user_form.items()
    }}

    user = await User.get(id)
    if not user:
        raise HTTPException(
            status_code=404,
            detail="Review record not found!"
        )

    await user.update(update_query)
    return user


@router.delete("/{id}", response_description="User record deleted from the database")
async def delete(id: PydanticObjectId, user=Depends(get_current_superuser)) -> dict:
    record = await User.get(id)

    if not record:
        raise HTTPException(
            status_code=404,
            detail="Review record not found!"
        )

    await record.delete()
    return {
        "message": "Record deleted successfully"
    }
