from django.db import transaction
from rest_framework import serializers as serializer

from console.electrical_info.models import ElectricalInfromation
from console.electricity_bill.models import TariffType, ElectricityBill

from console.electricity_bill.models import CustomerBillingType


class CreateElectricityBillSerializer(serializer.Serializer):
    electrical_id = serializer.IntegerField(required=True,
                                            allow_null=False,
                                            help_text="所属电源编号")
    year_month = serializer.CharField(max_length=32,
                                      required=True,
                                      help_text="年月",
                                      allow_null=False,
                                      allow_blank=False)
    peak_volume = serializer.FloatField(required=False,
                                        allow_null=True,
                                        help_text="峰电量")
    peak_volume2 = serializer.FloatField(required=False,
                                         allow_null=True,
                                         help_text="峰电量2")
    tip_volume = serializer.FloatField(required=False,
                                       allow_null=True,
                                       help_text="尖电量")
    tip_volume2 = serializer.FloatField(required=False,
                                        allow_null=True,
                                        help_text="尖电量2")
    usual_volume = serializer.FloatField(required=False,
                                         allow_null=True,
                                         help_text="平电量")
    usual_volume2 = serializer.FloatField(required=False,
                                          allow_null=True,
                                          help_text="平电量2")
    valley_volume = serializer.FloatField(required=False,
                                          allow_null=True,
                                          help_text="谷电量")
    valley_volume2 = serializer.FloatField(required=False,
                                           allow_null=True,
                                           help_text="谷电量2")
    other_volume = serializer.FloatField(required=False,
                                         allow_null=True,
                                         help_text="其他电量")
    peak_price = serializer.FloatField(help_text="峰电价",
                                       required=False,
                                       allow_null=True)
    peak_price2 = serializer.FloatField(help_text="峰电价2",
                                        required=False,
                                        allow_null=True)
    tip_price = serializer.FloatField(help_text="尖电价",
                                      required=False,
                                      allow_null=True)
    tip_price2 = serializer.FloatField(help_text="尖电价2",
                                       required=False,
                                       allow_null=True)
    usual_price = serializer.FloatField(help_text="平电价",
                                        required=False,
                                        allow_null=True)
    usual_price2 = serializer.FloatField(help_text="平电价2",
                                         required=False,
                                         allow_null=True)
    valley_price = serializer.FloatField(help_text="谷电价",
                                         required=False,
                                         allow_null=True)
    valley_price2 = serializer.FloatField(help_text="谷电价2",
                                          required=False,
                                          allow_null=True)
    other_price = serializer.FloatField(help_text="其他电价",
                                        required=False,
                                        allow_null=True)

    levy_fee = serializer.FloatField(help_text="代征费用",
                                     required=False,
                                     allow_null=True)
    power_factor = serializer.FloatField(help_text="考核功率因素",
                                         required=False,
                                         allow_null=True)
    power_factor_real = serializer.FloatField(help_text="实际功率因素",
                                              required=False,
                                              allow_null=True)
    power_factor_adjust = serializer.FloatField(help_text="力率",
                                                required=False,
                                                allow_null=True)
    report_md = serializer.FloatField(help_text="申报MD",
                                      required=False,
                                      allow_null=True)
    max_md = serializer.FloatField(default=0, help_text="最大MD")
    basic_price = serializer.FloatField(required=True,
                                        allow_null=False,
                                        help_text="基本电价")
    capacity = serializer.IntegerField(required=False,
                                       allow_null=True,
                                       help_text="总容量")
    idle_volume = serializer.IntegerField(required=False,
                                          allow_null=True,
                                          help_text="无功电量")
    amount = serializer.DecimalField(help_text="总金额",
                                     required=False,
                                     allow_null=True,
                                     max_digits=12,
                                     decimal_places=2)
    amount_adjust = serializer.FloatField(required=False,
                                          allow_null=True,
                                          help_text="力率调整")
    billing_type = serializer.IntegerField(required=True,
                                           allow_null=False,
                                           help_text="电价类型")
    # billing_method = serializer.CharField(required=True,
    #                                       allow_null=False,
    #                                       help_text="计费方式")
    basic_volume = serializer.FloatField(help_text="基本电费计费",
                                         required=False,
                                         allow_null=True)
    epidemic_discount = serializer.FloatField(help_text="防疫优惠电费",
                                              required=False,
                                              allow_null=True)
    refund_and_supplement_of_difference = serializer.FloatField(help_text="差额退补",
                                                                required=False,
                                                                allow_null=True)
    other_amount = serializer.DecimalField(help_text="其他金额",
                                           required=False,
                                           allow_null=True,
                                           max_digits=12,
                                           decimal_places=2)
    file = serializer.CharField(help_text="电费账单照片",
                                required=False,
                                allow_null=True)
    peak_md = serializer.FloatField(help_text="峰md",
                                    required=False,
                                    allow_null=True)
    usual_md1 = serializer.FloatField(help_text="平1md",
                                      required=False,
                                      allow_null=True)
    usual_md2 = serializer.FloatField(help_text="平2md",
                                      required=False,
                                      allow_null=True)
    valley_md = serializer.FloatField(help_text="谷md",
                                      required=False,
                                      allow_null=True)

    def validate(self, attrs):
        ele_info = ElectricalInfromation.objects.filter(
            id=attrs.get("electrical_id")).first()
        if not ele_info:
            raise serializer.ValidationError("电源编号%s不存在" %
                                             attrs.get("ele_info"))
        attrs["electrical_id"] = ele_info
        return attrs

    def create(self, validated_data):
        billing_type = validated_data.pop("billing_type")
        # billing_method = validated_data.pop("billing_method")
        obj = ElectricityBill.objects.filter(
            year_month=validated_data["year_month"],
            electrical_id=validated_data["electrical_id"])
        if not obj:
            instance = ElectricityBill.objects.create(**validated_data)
        else:
            obj.update(**validated_data)
            instance = ElectricityBill.objects.filter(
                id=obj.first().id).first()
        customer_billing_type = CustomerBillingType.objects.filter(
            ele_info=validated_data.get("electrical_id")).first()
        if not customer_billing_type:
            customer_billing_type = CustomerBillingType.objects.create(
                ele_info=validated_data.get("electrical_id"),
                ele_user=validated_data.get("electrical_id").electricity_user,
                customer=validated_data.get(
                    "electrical_id").electricity_user.customer if
                validated_data.get("electrical_id").electricity_user else None,
                billing_type_id=billing_type)
        customer_billing_type.billing_type_id = billing_type
        # customer_billing_type.billing_method = billing_method
        customer_billing_type.save()
        tr = TariffType.objects.filter(id=billing_type).first()
        tr.base_prise = validated_data.get("basic_price")
        tr.save()
        return instance


class ElectricityBillSerializer(serializer.ModelSerializer):
    electrical_info = serializer.SerializerMethodField()

    def get_electrical_info(self, obj):
        return {
            "power_number":
                obj.electrical_id.power_number,
            "magnification":
                obj.electrical_id.magnification,
            "transformer_capacity":
                obj.electrical_id.transformer_capacity,
            "real_capacity":
                obj.electrical_id.real_capacity,
            "customer":
                obj.electrical_id.electricity_user.customer.name
                if obj.electrical_id.electricity_user
                   and obj.electrical_id.electricity_user.customer else None
        } if obj.electrical_id else None

    class Meta:
        model = ElectricityBill
        fields = ("id", "electrical_info", "year_month", "peak_volume",
                  "peak_volume2", "tip_volume", "tip_volume2", "usual_volume",
                  "usual_volume2", "valley_volume", "valley_volume2",
                  "other_volume", "peak_price", "peak_price2", "tip_price",
                  "tip_price2", "usual_price", "usual_price2", "valley_price",
                  "valley_price2", "other_price", "levy_fee", "power_factor",
                  "power_factor_real", "power_factor_adjust", "report_md",
                  "max_md", "basic_price", "capacity", "idle_volume", "amount",
                  "amount_adjust", "basic_volume", "epidemic_discount", "refund_and_supplement_of_difference",
                  "other_amount", "file", "peak_md", "usual_md1", "usual_md2", "valley_md")


class UpdateElectricityBillSerializer(serializer.Serializer):
    peak_volume = serializer.FloatField(required=False,
                                        allow_null=True,
                                        help_text="峰电量")
    peak_volume2 = serializer.FloatField(required=False,
                                         allow_null=True,
                                         help_text="峰电量2")
    tip_volume = serializer.FloatField(required=False,
                                       allow_null=True,
                                       help_text="尖电量")
    tip_volume2 = serializer.FloatField(required=False,
                                        allow_null=True,
                                        help_text="尖电量2")
    usual_volume = serializer.FloatField(required=False,
                                         allow_null=True,
                                         help_text="平电量")
    usual_volume2 = serializer.FloatField(required=False,
                                          allow_null=True,
                                          help_text="平电量2")
    valley_volume = serializer.FloatField(required=False,
                                          allow_null=True,
                                          help_text="谷电量")
    valley_volume2 = serializer.FloatField(required=False,
                                           allow_null=True,
                                           help_text="谷电量2")
    other_volume = serializer.FloatField(required=False,
                                         allow_null=True,
                                         help_text="其他电量")
    peak_price = serializer.FloatField(help_text="峰电价",
                                       required=False,
                                       allow_null=True)
    peak_price2 = serializer.FloatField(help_text="峰电价2",
                                        required=False,
                                        allow_null=True)
    tip_price = serializer.FloatField(help_text="尖电价",
                                      required=False,
                                      allow_null=True)
    tip_price2 = serializer.FloatField(help_text="尖电价2",
                                       required=False,
                                       allow_null=True)
    usual_price = serializer.FloatField(help_text="平电价",
                                        required=False,
                                        allow_null=True)
    usual_price2 = serializer.FloatField(help_text="平电价2",
                                         required=False,
                                         allow_null=True)
    valley_price = serializer.FloatField(help_text="谷电价",
                                         required=False,
                                         allow_null=True)
    valley_price2 = serializer.FloatField(help_text="谷电价2",
                                          required=False,
                                          allow_null=True)
    other_price = serializer.FloatField(help_text="其他电价",
                                        required=False,
                                        allow_null=True)
    levy_fee = serializer.FloatField(help_text="代征费用",
                                     required=False,
                                     allow_null=True)
    power_factor = serializer.FloatField(help_text="考核功率因素",
                                         required=False,
                                         allow_null=True)
    power_factor_real = serializer.FloatField(help_text="实际功率因素",
                                              required=False,
                                              allow_null=True)
    power_factor_adjust = serializer.FloatField(help_text="力率",
                                                required=False,
                                                allow_null=True)
    report_md = serializer.FloatField(help_text="申报MD",
                                      required=False,
                                      allow_null=True)
    max_md = serializer.FloatField(default=0, help_text="最大MD")
    basic_price = serializer.FloatField(required=False,
                                        allow_null=True,
                                        help_text="基本电价")
    capacity = serializer.IntegerField(required=False,
                                       allow_null=True,
                                       help_text="总容量")
    idle_volume = serializer.FloatField(required=False,
                                        allow_null=True,
                                        help_text="无功电量")
    amount = serializer.DecimalField(help_text="总金额",
                                     required=False,
                                     allow_null=True,
                                     max_digits=12,
                                     decimal_places=2)
    amount_adjust = serializer.FloatField(required=False,
                                          allow_null=True,
                                          help_text="力率调整")
    billing_type = serializer.IntegerField(required=False,
                                           allow_null=True,
                                           help_text="电价类型")
    # billing_method = serializer.CharField(required=True,
    #                                       allow_null=False,
    #                                       help_text="计费方式")
    basic_volume = serializer.FloatField(help_text="基本电费计费",
                                         required=False,
                                         allow_null=True)
    epidemic_discount = serializer.DecimalField(help_text="防疫优惠电费",
                                                required=False,
                                                allow_null=True,
                                                max_digits=12,
                                                decimal_places=2)
    refund_and_supplement_of_difference = serializer.DecimalField(help_text="差额退补",
                                                                  required=False,
                                                                  allow_null=True,
                                                                  max_digits=12,
                                                                  decimal_places=2)
    other_amount = serializer.DecimalField(help_text="其他金额",
                                           required=False,
                                           allow_null=True,
                                           max_digits=12,
                                           decimal_places=2)
    file = serializer.CharField(help_text="电费账单照片",
                                required=False,
                                allow_null=True)
    peak_md = serializer.FloatField(help_text="峰md",
                                    required=False,
                                    allow_null=True)
    usual_md1 = serializer.FloatField(help_text="平1md",
                                      required=False,
                                      allow_null=True)
    usual_md2 = serializer.FloatField(help_text="平2md",
                                      required=False,
                                      allow_null=True)
    valley_md = serializer.FloatField(help_text="谷md",
                                      required=False,
                                      allow_null=True)

    @transaction.atomic()
    def update(self, instance, validated_data):
        point = transaction.savepoint()
        try:
            billing_type = validated_data.pop("billing_type")
            # billing_method = validated_data.pop("billing_method")

            customer_billing_type = CustomerBillingType.objects.filter(
                ele_info=instance.electrical_id).first()
            if not customer_billing_type:
                customer_billing_type = CustomerBillingType.objects.create(
                    ele_info=instance.electrical_id,
                    ele_user=instance.electrical_id.electricity_user
                    if instance.electrical_id else None,
                    customer=instance.electrical_id.electricity_user.customer
                    if instance.electrical_id.electricity_user else None,
                    billing_type_id=billing_type)
            customer_billing_type.billing_type_id = billing_type
            # customer_billing_type.billing_method = billing_method
            customer_billing_type.save()
            instance = ElectricityBill.objects.filter(id=instance.id).update(
                **validated_data)
            transaction.savepoint_commit(point)
        except Exception:
            transaction.savepoint_rollback(point)
        return instance


class TariffTypeSerializer(serializer.ModelSerializer):
    class Meta:
        model = TariffType
        fields = ("id", "name", "base_prise", "tip_prise", "peak_prise",
                  "flat_prise", "valley_prise", "is_summer", "voltage_level",
                  "enterprise_id", "area", "created_time", "updated_time",
                  "deleted", "deleted_time")


class TariffTypeCreateSerializer(serializer.Serializer):
    name = serializer.CharField(required=True, allow_null=False, max_length=64)
    base_prise = serializer.FloatField(required=False, allow_null=True)
    tip_prise = serializer.FloatField(required=False, allow_null=True)
    peak_prise = serializer.FloatField(required=False, allow_null=True)
    flat_prise = serializer.FloatField(required=False, allow_null=True)
    valley_prise = serializer.FloatField(required=False, allow_null=True)
    is_summer = serializer.BooleanField(required=False, allow_null=True)
    voltage_level = serializer.CharField(required=False,
                                         allow_null=True,
                                         allow_blank=True)
    enterprise_id = serializer.IntegerField(required=False, allow_null=True)
    area = serializer.CharField(required=False,
                                allow_null=True,
                                allow_blank=True)

    def create(self, validated_data):
        instance = TariffType.objects.create(**validated_data)

        return instance

    def update(self, instance, validated_data):
        instance = TariffType.objects.filter(id=instance.id).update(
            **validated_data)
        return instance


class CustomerBillingTypeSerializer(serializer.ModelSerializer):
    billing_type = serializer.SerializerMethodField()

    def get_billing_type(self, obj):
        return TariffTypeSerializer(obj.billing_type).data

    class Meta:
        model = CustomerBillingType
        fields = ("id", "customer_id", "ele_user_id", "ele_info_id",
                  "billing_type", "billing_method")
