from pydantic import BaseModel, ValidationError, StrictInt, StrictStr, StrictBool

from app.extensions.utils.log_helper import logger_
from core.domains.community.dto.community_dto import (
    CreateCommentDto,
    UpdateCommentDto,
    DeleteCommentDto,
    UpdateCommentLikeStatusDto,
    GetFeedsDto,
    GetPushFeedDto,
)
from core.exceptions import InvalidRequestException

logger = logger_.getLogger(__name__)


class CreateCommentSchema(BaseModel):
    post_id: StrictInt
    user_id: StrictInt
    body: StrictStr


class UpdateCommentSchema(BaseModel):
    comment_id: StrictInt
    user_id: StrictInt
    body: StrictStr


class DeleteCommentSchema(BaseModel):
    comment_id: StrictInt
    user_id: StrictInt


class UpdateCommentLikeStatusSchema(BaseModel):
    comment_id: StrictInt
    user_id: StrictInt
    is_liked: StrictBool


class GetFeedsSchema(BaseModel):
    user_id: StrictInt
    post_category_id: StrictInt
    previous_id: StrictInt | None


class GetNoticesSchema(BaseModel):
    user_id: StrictInt
    post_category_id: StrictInt
    previous_id: StrictInt | None


class GetPushFeedSchema(BaseModel):
    user_id: StrictInt
    post_id: StrictInt
    comment_id: StrictInt | None
    topic: StrictStr


class CreateCommentRequest:
    def __init__(self, user_id, post_id, body):
        self.user_id = int(user_id) if user_id else None
        self.post_id = int(post_id) if post_id else None
        self.body = body

    def validate_request_and_make_dto(self):
        try:
            schema = CreateCommentSchema(
                user_id=self.user_id, post_id=self.post_id, body=self.body,
            ).dict()
            return CreateCommentDto(**schema)
        except ValidationError as e:
            logger.error(
                f"[CreateCommentRequest][validate_request_and_make_dto] error : {e}"
            )
            raise InvalidRequestException(message=e.errors())


class UpdateCommentRequest:
    def __init__(self, user_id, comment_id, body):
        self.user_id = int(user_id) if user_id else None
        self.comment_id = int(comment_id) if comment_id else None
        self.body = body

    def validate_request_and_make_dto(self):
        try:
            schema = UpdateCommentSchema(
                user_id=self.user_id, comment_id=self.comment_id, body=self.body,
            ).dict()
            return UpdateCommentDto(**schema)
        except ValidationError as e:
            logger.error(
                f"[UpdateCommentRequest][validate_request_and_make_dto] error : {e}"
            )
            raise InvalidRequestException(message=e.errors())


class DeleteCommentRequest:
    def __init__(self, user_id, comment_id):
        self.user_id = int(user_id) if user_id else None
        self.comment_id = int(comment_id) if comment_id else None

    def validate_request_and_make_dto(self):
        try:
            schema = DeleteCommentSchema(
                user_id=self.user_id, comment_id=self.comment_id
            ).dict()
            return DeleteCommentDto(**schema)
        except ValidationError as e:
            logger.error(
                f"[DeleteCommentRequest][validate_request_and_make_dto] error : {e}"
            )
            raise InvalidRequestException(message=e.errors())


class UpdateCommentLikeStatusRequest:
    def __init__(self, user_id, comment_id, is_liked):
        self.user_id = int(user_id) if user_id else None
        self.comment_id = int(comment_id) if comment_id else None
        self.is_liked = is_liked

    def validate_request_and_make_dto(self):
        try:
            schema = UpdateCommentLikeStatusSchema(
                user_id=self.user_id, comment_id=self.comment_id, is_liked=self.is_liked
            ).dict()
            return UpdateCommentLikeStatusDto(**schema)
        except ValidationError as e:
            logger.error(
                f"[UpdateCommentLikeStatusRequest][validate_request_and_make_dto] error : {e}"
            )
            raise InvalidRequestException(message=e.errors())


class GetFeedsRequest:
    def __init__(self, user_id, post_category_id, previous_id):
        self.user_id = int(user_id) if user_id else None
        self.post_category_id = int(post_category_id) if post_category_id else None
        self.previous_id = int(previous_id) if previous_id else None

    def validate_request_and_make_dto(self):
        try:
            schema = GetFeedsSchema(
                user_id=self.user_id,
                post_category_id=self.post_category_id,
                previous_id=self.previous_id,
            ).dict()
            return GetFeedsDto(**schema)
        except ValidationError as e:
            logger.error(
                f"[GetFeedsRequest][validate_request_and_make_dto] error : {e}"
            )
            raise InvalidRequestException(message=e.errors())


class GetNoticesRequest:
    def __init__(self, user_id, previous_id):
        self.user_id = int(user_id) if user_id else None
        self.post_category_id = 100
        self.previous_id = int(previous_id) if previous_id else None

    def validate_request_and_make_dto(self):
        try:
            schema = GetNoticesSchema(
                user_id=self.user_id,
                post_category_id=self.post_category_id,
                previous_id=self.previous_id,
            ).dict()
            return GetFeedsDto(**schema)
        except ValidationError as e:
            logger.error(
                f"[GetNoticesRequest][validate_request_and_make_dto] error : {e}"
            )
            raise InvalidRequestException(message=e.errors())


class GetPushFeedRequest:
    def __init__(self, user_id, post_id, comment_id, topic):
        self.user_id = int(user_id) if user_id else None
        self.post_id = int(post_id) if post_id else None
        self.comment_id = int(comment_id) if comment_id else None
        self.topic = topic

    def validate_request_and_make_dto(self):
        try:
            schema = GetPushFeedSchema(
                user_id=self.user_id,
                post_id=self.post_id,
                comment_id=self.comment_id,
                topic=self.topic,
            ).dict()
            return GetPushFeedDto(**schema)
        except ValidationError as e:
            logger.error(
                f"[GetPushFeedRequest][validate_request_and_make_dto] error : {e}"
            )
            raise InvalidRequestException(message=e.errors())
