

import bson
from bson import ObjectId
from fastapi import APIRouter, HTTPException, status
from fastapi.params import Depends
import pymongo

from app.dto import UserDTO
from app.models import HTTPError, User
from .utils import get_current_user, objectid_misformatted
import app.config as config

# Database setup
client = pymongo.MongoClient(config.MONGODB_URL, username=config.MONGODB_USERNAME, password=config.MONGODB_PASSWORD)
db = client[config.MONGODB_DATABASE]

users_collection = db["users"]

# Best workaround found for _id typed as ObjectId (creating Exception bcause JSON doesn't support custom types countrary to BSON, used by Mongo)
# also allows to create DTOs at the time, but not at it's best (project structure is chaotic FTM :s)
import app.serializers as serializers # Import all serializers (detailed in __init__.py) 

users_router = APIRouter(
    prefix="/user",
    tags=["Users"]
)

@users_router.get(
    path="s",
    responses={401: {"model": HTTPError}, 422: {"model": HTTPError}},
    response_model=list[UserDTO]
)
async def search_users(name: str, current_user: User = Depends(get_current_user)):
    try:
        users = serializers.users_serialize(users_collection.find({"username": {"$regex": name, "$options": "i"}}).to_list())
    except pymongo.errors.OperationFailure:
        raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Regex may be wrongly formatted")
    
    return users

@users_router.get(
    path="/{id}",
    responses={401: {"model": HTTPError}, 422: {"model": HTTPError}, 404: {"model": HTTPError}},
    response_model=UserDTO
)
async def get_user(id: str, current_user: User = Depends(get_current_user)):
    try:
        user = users_collection.find_one({"_id": ObjectId(id)})
    except bson.errors.InvalidId:
        objectid_misformatted()
    
    if user is None:
        raise HTTPException(status_code=404, detail="User not found")
    
    return serializers.user_serialize(user)