from flask_jwt_extended import create_access_token, create_refresh_token

from app.extensions.database import session
from app.extensions.utils.log_helper import logger_
from app.extensions.utils.time_helper import (
    get_jwt_access_expired_timestamp,
    get_jwt_refresh_expired_timestamp,
)
from app.persistence.model import BlacklistModel, JwtModel
from core.domains.authentication.dto.auth_dto import GetBlacklistDto
from core.domains.user.entity.user_entity import BlacklistEntity, JwtEntity
from core.exceptions import UpdateFailErrorException

logger = logger_.getLogger(__name__)


class AuthenticationRepository:
    def create_blacklist(self, dto: GetBlacklistDto) -> None:
        blacklist = BlacklistModel(
            user_id=dto.user_id,
            access_token=dto.access_token,
            expired_at=get_jwt_access_expired_timestamp(),
        )
        try:
            session.add(blacklist)
            session.commit()
        except Exception as e:
            session.rollback()
            logger.error(
                f"[AuthenticationRepository][create_blacklist] user_id : {dto.user_id}, "
                f"access_token : {dto.access_token} error : {e}"
            )

    def get_blacklist_by_dto(self, dto: GetBlacklistDto) -> BlacklistEntity | None:
        blacklist = (
            session.query(BlacklistModel)
            .filter_by(access_token=dto.access_token)
            .first()
        )

        if not blacklist:
            return None
        return blacklist.to_entity()

    def get_jwt(self, user_id: int) -> JwtEntity | None:
        token_info = session.query(JwtModel).filter_by(user_id=user_id).first()

        if not token_info:
            return None

        return token_info.to_entity()

    def update_jwt(self, user_id: int) -> None:
        """
            새로운 Token 생성
            update 시간 갱신
        """
        try:
            session.query(JwtModel).filter_by(user_id=user_id).update(
                {
                    "access_token": create_access_token(identity=user_id),
                    "refresh_token": create_refresh_token(identity=user_id),
                    "access_expired_at": get_jwt_access_expired_timestamp(),
                    "refresh_expired_at": get_jwt_refresh_expired_timestamp(),
                }
            )
            session.commit()
        except Exception as e:
            session.rollback()
            logger.error(
                f"[AuthenticationRepository][update_jwt] user_id : {user_id} "
                f"error : {e}"
            )
            raise UpdateFailErrorException(msg=f"Failed update jwt")
