from marshmallow import fields, post_load, pre_dump

from maps_adv.adv_store.api.proto import billing_pb2
from maps_adv.adv_store.api.proto import charger_api_pb2
from maps_adv.adv_store.api.schemas.enums import (
    ReasonCampaignStoppedEnum,
    FixTimeIntervalEnum,
)
from maps_adv.common.protomallow import (
    PbDateTimeField,
    PbEnumField,
    PbFixedDecimalDictField,
    ProtobufSchema,
)

from .enums_map import ENUMS_MAP


class CampaignForChargerSchema(ProtobufSchema):
    class Meta:
        pb_message_class = charger_api_pb2.CampaignForCharger

    campaign_id = fields.Integer()
    order_id = fields.Integer(required=False)
    cost = PbFixedDecimalDictField(places=4, field="value")
    budget = PbFixedDecimalDictField(places=4, field="value", required=False)
    daily_budget = PbFixedDecimalDictField(places=4, field="value", required=False)
    timezone = fields.String()

    @post_load
    def postload(self, data):
        data.setdefault("budget")
        data.setdefault("daily_budget")
        data.setdefault("order_id")


class CampaignForChargerListSchema(ProtobufSchema):
    class Meta:
        pb_message_class = charger_api_pb2.CampaignForChargerList

    campaigns = fields.Nested(CampaignForChargerSchema, many=True)

    @post_load
    def postload(self, data):
        return data["campaigns"]


class CampaignForChargerCpaSchema(ProtobufSchema):
    class Meta:
        pb_message_class = charger_api_pb2.CampaignForChargerCpa

    campaign_id = fields.Integer()
    order_id = fields.Integer(required=False)
    cost = PbFixedDecimalDictField(places=4, field="value")
    budget = PbFixedDecimalDictField(places=4, field="value", required=False)
    daily_budget = PbFixedDecimalDictField(places=4, field="value", required=False)
    timezone = fields.String()
    paid_events_names = fields.List(fields.String())

    @post_load
    def postload(self, data):
        data.setdefault("budget")
        data.setdefault("daily_budget")
        data.setdefault("order_id")


class CampaignForChargerCpaListSchema(ProtobufSchema):
    class Meta:
        pb_message_class = charger_api_pb2.CampaignForChargerCpaList

    campaigns = fields.Nested(CampaignForChargerCpaSchema, many=True)

    @post_load
    def postload(self, data):
        return data["campaigns"]


class CampaignToStopSchema(ProtobufSchema):
    class Meta:
        pb_message_class = charger_api_pb2.CampaignToStop

    campaign_id = fields.Integer()
    reason_stopped = PbEnumField(
        enum=ReasonCampaignStoppedEnum,
        pb_enum=charger_api_pb2.ReasonStopped.Enum,
        values_map=ENUMS_MAP["reason_stopped"],
    )

    @pre_dump
    def predump(self, data):
        (campaign_id, reason_stopped) = data
        return {"campaign_id": campaign_id, "reason_stopped": reason_stopped}


class CampaignsToStopListSchema(ProtobufSchema):
    class Meta:
        pb_message_class = charger_api_pb2.CampaignsToStopList

    processed_at = PbDateTimeField()
    campaigns = fields.Nested(CampaignToStopSchema, many=True)

    @pre_dump
    def predump(self, data):
        data["campaigns"] = list(data["campaigns"].items())


class CampaignForChargerFixSchema(ProtobufSchema):
    class Meta:
        pb_message_class = charger_api_pb2.CampaignForChargerFix

    campaign_id = fields.Integer()
    order_id = fields.Integer()
    cost = PbFixedDecimalDictField(places=4, field="value")
    time_interval = PbEnumField(
        enum=FixTimeIntervalEnum,
        pb_enum=billing_pb2.Fix.TimeIntervalEnum,
        values_map=ENUMS_MAP["time_interval"],
    )
    paid_till = PbDateTimeField(required=False)
    timezone = fields.String()


class CampaignForChargerFixListSchema(ProtobufSchema):
    class Meta:
        pb_message_class = charger_api_pb2.CampaignForChargerFixList

    campaigns = fields.Nested(CampaignForChargerFixSchema, many=True)

    @post_load
    def postload(self, data):
        return data["campaigns"]
