import sentry_sdk
from flask import Blueprint
from flask_jwt_extended.exceptions import NoAuthorizationError
from jwt import ExpiredSignatureError

from core.exceptions import TokenValidationErrorException

api: Blueprint = Blueprint(name="api/groot", import_name=__name__)

from .authentication.v1.auth_view import *  # noqa isort:skip

from .user.v1.user_view import *  # noqa isort:skip
from .plant.v1.plant_view import *  # noqa isort:skip
from .community.v1.community_view import *  # noqa isort:skip
from .iot.v1.iot_view import *  # noqa isort:skip
from .cs.v1.cs_view import *  # noqa isort:skip
from .admin.v1.admin_view import *  # noqa isort:skip
from .main import *  # noqa isort:skip
from .oauth.v1.oauth_view import *  # noqa isort:skip
from .notification.v1.notification_view import *  # noqa isort:skip
from .authentication.v1.auth_view import *  # noqa isort:skip


@api.errorhandler(Exception)
def handle_custom_type_exception(error):
    sentry_sdk.capture_exception(error)
    check_custom_err = getattr(error, "type_", None)
    if check_custom_err:
        return {"detail": error.type_["type_"], "message": error.msg}, error.code
    elif isinstance(check_custom_err, dict):
        return {"detail": error.code, "message": error.msg}, error.code
    else:
        return (
            {"detail": HTTPStatus.INTERNAL_SERVER_ERROR, "message": str(error),},
            HTTPStatus.INTERNAL_SERVER_ERROR,
        )


@api.errorhandler(InvalidRequestException)
def handle_invalid_request_exception(error):
    sentry_sdk.capture_exception(error)
    return (
        {"detail": error.message[0]["loc"][0], "message": "invalid_request_error"},
        error.status_code,
    )


@api.errorhandler(NoAuthorizationError)
def handle_no_authorization_exception(error):
    sentry_sdk.capture_exception(error)
    return (
        {"detail": HTTPStatus.UNAUTHORIZED, "message": "unauthorized_error"},
        HTTPStatus.UNAUTHORIZED,
    )


@api.errorhandler(ExpiredSignatureError)
def handle_signature_has_expired_exception(error):
    sentry_sdk.capture_exception(error)
    return (
        {"type": HTTPStatus.UNAUTHORIZED, "message": "Signature has expired"},
        HTTPStatus.UNAUTHORIZED,
    )


@api.errorhandler(TokenValidationErrorException)
def handle_token_validation_exception(error):
    sentry_sdk.capture_exception(error)
    return (
        {"detail": error.code, "message": error.msg},
        error.code,
    )
