import uuid
from fastapi import APIRouter, Request

from fastapi.responses import JSONResponse

from ..scheduler import regenerate_interventions_for_client

from ..utils import MONGODB_DATABASE, mongodb_connect, check_access, get_user_sub, get_roles
from ..models.pools import Pool, UpdatePool

mongodb_client = mongodb_connect()
router = APIRouter(
    prefix="/pools",
    tags=["pools"],
    responses={404: {"description": "Not found"}},
)


@router.post("/{client_sub}")
async def create_pool(request: Request, client_sub: str, pool: Pool):
    """Create a new pool."""
    try:
        auth_token = request.headers["authorization"].replace("Bearer ", "")
        check_access(auth_token, ["see"])
        my_user_sub = get_user_sub(auth_token)

        client_cursor = mongodb_client[MONGODB_DATABASE]["clients"].find_one(
            {"sub": client_sub},
            {"_id": 0, "sub": 1}
        )

        if not client_cursor:
            responseObject = {
                "status": "error",
                "endpoint": "CreatePool",
                "message": f"Client '{client_sub}' n'existe pas"
            }
            return JSONResponse(content=responseObject, status_code=404)

        sub = str(uuid.uuid4())
        pool_dict = pool.model_dump()
        pool_dict["sub"] = sub
        pool_dict["client_sub"] = client_sub
        pool_dict["created_by_sub"] = my_user_sub

        mongodb_client[MONGODB_DATABASE]["pools"].insert_one(pool_dict)

        await regenerate_interventions_for_client(client_sub)

        responseObject = {
            "status": "success",
            "endpoint": "CreatePool",
            "message": "Piscine créé avec succès.",
            "sub": sub
        }
        return JSONResponse(content=responseObject, status_code=200)
    except Exception as e:
        responseObject = {
            "status": "error",
            "endpoint": "CreatePool",
            "message": f"Error lors de l'enregistrement de la piscine: {str(e)}"
        }
        return JSONResponse(content=responseObject, status_code=500)


@router.get("/{client_sub}")
async def get_pool_list(request: Request, client_sub: str):
    """Get all pools."""
    try:
        auth_token = request.headers["authorization"].replace("Bearer ", "")
        check_access(auth_token, ["*"])

        pools = mongodb_client[MONGODB_DATABASE]["pools"].find(
            {"client_sub": client_sub},
            {"_id": 0, "sub": 1, "photo": 1, "description": 1, "gps": 1, "client_sub": 1}
        )
        responseObject = {
            "status": "success",
            "endpoint": "GetPoolList",
            "message": "Liste de piscine récupéré avec succès",
            "content": list(pools)
        }
        return JSONResponse(content=responseObject, status_code=200)
    except Exception as e:
        responseObject = {
            "status": "error",
            "endpoint": "GetPoolList",
            "message": f"Error lors de la récupération des piscines: {str(e)}",
        }
        return JSONResponse(content=responseObject, status_code=500)


@router.get("/pool/{sub}")
async def get_pool(request: Request, sub: str):
    """Get a pool by its sub."""
    try:
        auth_token = request.headers["authorization"].replace("Bearer ", "")
        check_access(auth_token, ["*"])
        pool = mongodb_client[MONGODB_DATABASE]["pools"].find_one(
            {"sub": sub},
            {"_id": 0}
        )

        if not pool:
            responseObject = {
                "status": "error",
                "endpoint": "GetPool",
                "message": f"Piscine '{sub}' n'existe pas",
            }
            return JSONResponse(content=responseObject, status_code=404)

        responseObject = {
            "status": "success",
            "endpoint": "GetPool",
            "message": f"Piscine '{sub}' récupéré avec succès",
            "content": pool
        }
        return JSONResponse(content=responseObject, status_code=200)
    except Exception as e:
        responseObject = {
            "status": "error",
            "endpoint": "GetPool",
            "message": f"Error lors de la récupération de la piscine: {str(e)}",
        }
        return JSONResponse(content=responseObject, status_code=500)


@router.patch("/pool/{sub}")
async def update_pool(request: Request, sub: str, pool: UpdatePool):
    """update a pool by its sub."""
    try:
        auth_token = request.headers["authorization"].replace("Bearer ", "")
        check_access(auth_token, ["see"])
        pool_cursor = mongodb_client[MONGODB_DATABASE]["pools"].find_one(
            {"sub": sub},
            {"_id": 0}
        )

        pool_dict = pool.model_dump()

        if not pool_cursor:
            responseObject = {
                "status": "error",
                "endpoint": "UpdatePool",
                "message": f"Piscine '{sub}' n'existe pas",
            }
            return JSONResponse(content=responseObject, status_code=404)

        mongodb_client[MONGODB_DATABASE]["pools"].update_one(
            {"sub": sub},
            {"$set": pool_dict}
        )

        responseObject = {
            "status": "success",
            "endpoint": "UpdatePool",
            "message": f"Piscine '{sub}' mis à jour avec succès",
        }
        return JSONResponse(content=responseObject, status_code=200)
    except Exception as e:
        responseObject = {
            "status": "error",
            "endpoint": "UpdatePiscine",
            "message": f"Error lors de la mise à jour de la piscine: {str(e)}",
        }
        return JSONResponse(content=responseObject, status_code=500)


@router.delete("/pool/{sub}")
async def delete_pool(request: Request, sub: str):
    """Delete a pool by its sub."""
    try:
        auth_token = request.headers["authorization"].replace("Bearer ", "")
        check_access(auth_token, ["see"])

        pool_cursor = mongodb_client[MONGODB_DATABASE]["pools"].find_one(
            {"sub": sub},
            {"_id": 0, "sub": 1}
        )

        if not pool_cursor:
            responseObject = {
                "status": "error",
                "endpoint": "DeletePool",
                "message": f"Piscine '{sub}' n'existe pas",
            }
            return JSONResponse(content=responseObject, status_code=404)
        
        result = mongodb_client[MONGODB_DATABASE]["pools"].delete_one(
            {"sub": sub}
        )

        if not result:
            responseObject = {
                "status": "error",
                "endpoint": "DeletePool",
                "message": f"Vous n'avez pas le droit d'accès à cette ressource",
            }
            return JSONResponse(content=responseObject, status_code=403)

        responseObject = {
            "status": "success",
            "endpoint": "DeletePool",
            "message": f"Piscine '{sub}' supprimée avec succès",
        }
        return JSONResponse(content=responseObject, status_code=200)
    except Exception as e:
        responseObject = {
            "status": "error",
            "endpoint": "Delete",
            "message": f"Error lors de la suppression de la piscine: {str(e)}",
        }
        return JSONResponse(content=responseObject, status_code=500)
