import datetime
from uuid import UUID
from api.actions import storage
from fastapi import HTTPException
from api.models.usuario import Usuario
from starlette.requests import Request
from api.dependencies import validar_email, validar_formato_fecha,validar_edad

FORMATO_FECHA = "%Y-%m-%d"
EDAD_MINIMA = 18
EDAD_MAXIMA = 100

class Usuarios_Services:
    """ Sección de servicios para el manejo de la logica de negocio
    
    Attributes:
        FORMATO_FECHA (str): Formato de fecha para validar
        EDAD_MINIMA (int): Edad minima para validar
        EDAD_MAXIMA (int): Edad maxima para validar
    """

    def agregar_usuario(self, usuario: Usuario, request: Request) -> dict:
        """ Agrega un usuario a la base de datos.

        :param usuario: Usuario a agregar
        :param request: Request de FastAPI
        """
        try:

            if not validar_email(getattr(usuario, "email")):
                raise HTTPException(
                    status_code=400,
                    detail="El email no es válido"

                )

            fecha_nacimiento = usuario.fecha_nacimiento
            
            if not validar_formato_fecha(fecha_nacimiento, FORMATO_FECHA):
                raise HTTPException(
                    status_code=400,
                    detail="El formato de la fecha de nacimiento no es válida"
                )

            usuario.fecha_nacimiento = datetime.datetime.strptime(fecha_nacimiento, FORMATO_FECHA)
            
            if not validar_edad(usuario.fecha_nacimiento, EDAD_MINIMA, EDAD_MAXIMA):
                raise HTTPException(
                    status_code=400,
                    detail="La edad no es válida"
                )

            usuario_id = storage.add(usuario, request)

            return { "ID": usuario_id }
        
        except Exception as e:
            print("Error al agregar usuario: {}".format(str(e)))
            raise e


    def editar_usuario(self, usuario_id: UUID, usuario: Usuario, request: Request) -> dict:
        """ Edita un usuario de la base de datos.

        :param usuario_id: ID del usuario a editar
        :param usuario: Usuario a editar
        :param request: Request de FastAPI
        """
        try:
                
            if not validar_email(getattr(usuario, "email")):
                raise HTTPException(
                    status_code=400,
                    detail="El email no es válido"

                )

            fecha_nacimiento = usuario.fecha_nacimiento
            
            if not validar_formato_fecha(fecha_nacimiento, FORMATO_FECHA):
                raise HTTPException(
                    status_code=400,
                    detail="El formato de la fecha de nacimiento no es válida"
                )

            usuario.fecha_nacimiento = datetime.datetime.strptime(fecha_nacimiento, FORMATO_FECHA)
            
            if not validar_edad(usuario.fecha_nacimiento, EDAD_MINIMA, EDAD_MAXIMA):
                raise HTTPException(
                    status_code=400,
                    detail="La edad no es válida"
                )

            storage.update(usuario_id, usuario, request)

            return { "ID": usuario_id }

        except Exception as e:
            print("Error al editar usuario: {}".format(str(e)))
            raise e


    def eliminar_usuario(self, usuario_id: UUID, request: Request) -> dict:
        """ Elimina un usuario de la base de datos.

        :param usuario_id: ID del usuario a eliminar
        :param request: Request de FastAPI
        """
        try:

            storage.delete(Usuario, usuario_id, request)

            return { "ID": usuario_id }

        except Exception as e:
            print("Error al eliminar usuario: {}".format(str(e)))
            raise e


    def listar_usuarios(self, pagina: int, cantidad: int, order_by: str, sort: str, request: Request)-> dict:
        """ Obtiene una lista de usuarios de la base de datos.
        
        :param pagina: Pagina a retornar
        :param cantidad: Cantidad de usuarios a retornar
        :param order_by: Campo por el cual se ordenará la lista
        :param sort: Orden ascendente o descendente
        :param request: Request de FastAPI
        """
        try:

            return storage.get_all(Usuario, pagina, cantidad, request, order_by, sort)

        except Exception as e:
            print("Error al listar usuarios: {}".format(str(e)))
            raise e


    def obtener_usuario(self, usuario_id: UUID, request: Request) -> Usuario:
        """ Retorna un usuario por su ID

        :param usuario_id: ID del usuario a consultar
        :param request: Request de FastAPI
        """
        try:

            usuario = storage.get_by_id(Usuario, usuario_id, request)

            return usuario

        except Exception as e:
            print("Error al obtener usuario: {}".format(str(e)))
            raise e
[((45, 39, 45, 98), 'datetime.datetime.strptime', 'datetime.datetime.strptime', ({(45, 66, 45, 82): 'fecha_nacimiento', (45, 84, 45, 97): 'FORMATO_FECHA'}, {}), '(fecha_nacimiento, FORMATO_FECHA)', False, 'import datetime\n'), ((53, 25, 53, 54), 'api.actions.storage.add', 'storage.add', ({(53, 37, 53, 44): 'usuario', (53, 46, 53, 53): 'request'}, {}), '(usuario, request)', False, 'from api.actions import storage\n'), ((86, 39, 86, 98), 'datetime.datetime.strptime', 'datetime.datetime.strptime', ({(86, 66, 86, 82): 'fecha_nacimiento', (86, 84, 86, 97): 'FORMATO_FECHA'}, {}), '(fecha_nacimiento, FORMATO_FECHA)', False, 'import datetime\n'), ((94, 12, 94, 56), 'api.actions.storage.update', 'storage.update', ({(94, 27, 94, 37): 'usuario_id', (94, 39, 94, 46): 'usuario', (94, 48, 94, 55): 'request'}, {}), '(usuario_id, usuario, request)', False, 'from api.actions import storage\n'), ((111, 12, 111, 56), 'api.actions.storage.delete', 'storage.delete', ({(111, 27, 111, 34): 'Usuario', (111, 36, 111, 46): 'usuario_id', (111, 48, 111, 55): 'request'}, {}), '(Usuario, usuario_id, request)', False, 'from api.actions import storage\n'), ((131, 19, 131, 86), 'api.actions.storage.get_all', 'storage.get_all', ({(131, 35, 131, 42): 'Usuario', (131, 44, 131, 50): 'pagina', (131, 52, 131, 60): 'cantidad', (131, 62, 131, 69): 'request', (131, 71, 131, 79): 'order_by', (131, 81, 131, 85): 'sort'}, {}), '(Usuario, pagina, cantidad, request, order_by, sort)', False, 'from api.actions import storage\n'), ((146, 22, 146, 69), 'api.actions.storage.get_by_id', 'storage.get_by_id', ({(146, 40, 146, 47): 'Usuario', (146, 49, 146, 59): 'usuario_id', (146, 61, 146, 68): 'request'}, {}), '(Usuario, usuario_id, request)', False, 'from api.actions import storage\n'), ((31, 22, 35, 17), 'fastapi.HTTPException', 'HTTPException', (), '', False, 'from fastapi import HTTPException\n'), ((39, 19, 39, 73), 'api.dependencies.validar_formato_fecha', 'validar_formato_fecha', ({(39, 41, 39, 57): 'fecha_nacimiento', (39, 59, 39, 72): 'FORMATO_FECHA'}, {}), '(fecha_nacimiento, FORMATO_FECHA)', False, 'from api.dependencies import validar_email, validar_formato_fecha, validar_edad\n'), ((40, 22, 43, 17), 'fastapi.HTTPException', 'HTTPException', (), '', False, 'from fastapi import HTTPException\n'), ((47, 19, 47, 83), 'api.dependencies.validar_edad', 'validar_edad', ({(47, 32, 47, 56): 'usuario.fecha_nacimiento', (47, 58, 47, 69): 'EDAD_MINIMA', (47, 71, 47, 82): 'EDAD_MAXIMA'}, {}), '(usuario.fecha_nacimiento, EDAD_MINIMA, EDAD_MAXIMA)', False, 'from api.dependencies import validar_email, validar_formato_fecha, validar_edad\n'), ((48, 22, 51, 17), 'fastapi.HTTPException', 'HTTPException', (), '', False, 'from fastapi import HTTPException\n'), ((72, 22, 76, 17), 'fastapi.HTTPException', 'HTTPException', (), '', False, 'from fastapi import HTTPException\n'), ((80, 19, 80, 73), 'api.dependencies.validar_formato_fecha', 'validar_formato_fecha', ({(80, 41, 80, 57): 'fecha_nacimiento', (80, 59, 80, 72): 'FORMATO_FECHA'}, {}), '(fecha_nacimiento, FORMATO_FECHA)', False, 'from api.dependencies import validar_email, validar_formato_fecha, validar_edad\n'), ((81, 22, 84, 17), 'fastapi.HTTPException', 'HTTPException', (), '', False, 'from fastapi import HTTPException\n'), ((88, 19, 88, 83), 'api.dependencies.validar_edad', 'validar_edad', ({(88, 32, 88, 56): 'usuario.fecha_nacimiento', (88, 58, 88, 69): 'EDAD_MINIMA', (88, 71, 88, 82): 'EDAD_MAXIMA'}, {}), '(usuario.fecha_nacimiento, EDAD_MINIMA, EDAD_MAXIMA)', False, 'from api.dependencies import validar_email, validar_formato_fecha, validar_edad\n'), ((89, 22, 92, 17), 'fastapi.HTTPException', 'HTTPException', (), '', False, 'from fastapi import HTTPException\n')]