from marshmallow import ValidationError, fields, validate, validates_schema

from maps_adv.adv_store.api.proto import campaign_list_pb2, moderation_pb2
from maps_adv.adv_store.api.proto.campaign_pb2 import (
    Platform,
)
from maps_adv.adv_store.api.proto.error_pb2 import Error
from maps_adv.adv_store.api.schemas.enums import (
    ModerationResolutionEnum,
    PlatformEnum,
)
from maps_adv.common.helpers.enums import CampaignTypeEnum
from maps_adv.common.proto.campaign_pb2 import CampaignType
from maps_adv.common.protomallow import (
    PbDateTimeField,
    PbEnumField,
    PbFixedDecimalDictField,
    ProtobufSchema,
)

from .enums_map import ENUMS_MAP


class CampaignModerationInfoSchema(ProtobufSchema):
    class Meta:
        pb_message_class = campaign_list_pb2.CampaignModerationInfo

    id = fields.Integer()
    name = fields.String()
    campaign_type = PbEnumField(
        enum=CampaignTypeEnum,
        pb_enum=CampaignType.Enum,
        values_map=ENUMS_MAP["campaign_type"],
    )
    start_datetime = PbDateTimeField()
    end_datetime = PbDateTimeField()
    timezone = fields.String()
    request_datetime = PbDateTimeField()
    platforms = fields.List(
        PbEnumField(
            enum=PlatformEnum,
            pb_enum=Platform.Enum,
            values_map=ENUMS_MAP["platforms"],
        )
    )
    manul_order_id = fields.Integer(required=False)
    order_id = fields.Integer(required=False)
    budget = PbFixedDecimalDictField(places=4, field="value", required=False)


class CampaignModerationInfoListSchema(ProtobufSchema):
    class Meta:
        pb_message_class = campaign_list_pb2.CampaignModerationInfoList

    campaigns = fields.List(fields.Nested(CampaignModerationInfoSchema))


class CampaignModerationReviewSchema(ProtobufSchema):
    class Meta:
        pb_message_class = moderation_pb2.CampaignModerationReview

    resolution = PbEnumField(
        enum=ModerationResolutionEnum,
        pb_enum=moderation_pb2.CampaignModerationReview.ReviewResolution,
        values_map=[
            (
                moderation_pb2.CampaignModerationReview.ReviewResolution.APPROVE,
                ModerationResolutionEnum.APPROVE,
            ),
            (
                moderation_pb2.CampaignModerationReview.ReviewResolution.REJECT,
                ModerationResolutionEnum.REJECT,
            ),
        ],
    )
    author_id = fields.Integer()
    comment = fields.String(missing="")
    campaign_id = fields.Integer()
    verdicts = fields.List(fields.Integer(validate=validate.Range(min=0)), missing=list)

    @validates_schema
    def validate_verdicts(self, data):
        if data["resolution"] == ModerationResolutionEnum.APPROVE and data["verdicts"]:
            raise ValidationError(
                "APPROVE resolution cannot have verdicts",
                "verdicts",
                pb_error_code=Error.INVALID_INPUT_DATA,
            )
