import datetime
import zlib
import pickle

from rest_framework import serializers
from rest_framework.relations import PrimaryKeyRelatedField
from rest_framework.serializers import ModelSerializer

from common.third_party_api.amap.openapi import AmapApi
from common.utils.exceptions import ValidationError
from common.accounts.models import Users
from console.powerstation.models import PowerStation, Outline, Circuit
from ..customer.models import Customer
from ..electrical_info.models import ElectricalInfromation
from ..electrical_info.serializers import ElectricalInfromationSerializer
from ..electricityuser.models import ElectricityUser
from ..team.models import Team


class OutlineSerializer(ModelSerializer):
    power_number = serializers.SerializerMethodField()

    def get_power_number(self, obj):
        ele_info = ElectricalInfromation.objects.filter(id=obj.power_number).first()
        return {
            "id": ele_info.id,
            "power_number": ele_info.power_number
        } if ele_info else None

    class Meta:
        model = Outline
        fields = ('id', 'name', 'powerstation', "power_number")


class OutlineInfoSerializer(serializers.Serializer):
    name = serializers.CharField(required=False, allow_null=True, allow_blank=True)
    # powerstation_id = serializers.IntegerField(required=False, allow_null=True)
    power_number = serializers.CharField(required=False, allow_null=True, allow_blank=True)

    def update(self, instance, validated_data):
        instance.name = validated_data.get("name")
        instance.power_number = validated_data.get("power_number")
        instance.save()
        return instance

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


class PowerStationSerializer(ModelSerializer):
    service_team = serializers.CharField(required=True,
                                         allow_null=False,
                                         allow_blank=False)
    # customer = SerializerMethodField()
    # electricity_user = SerializerMethodField()
    #
    # def get_customer(self, obj):
    #     return CustomerInfoSerializer(obj.customer).data
    #
    # def get_electricity_user(self, obj):
    #     return ElectricityUserSerializer(obj.electricity_user).data
    # customer = PrimaryKeyRelatedField(queryset=Customer.objects.all())
    inspector_ids = serializers.CharField(required=False,
                                          allow_null=True,
                                          allow_blank=True)
    electricity_user = PrimaryKeyRelatedField(
        queryset=ElectricityUser.objects.all())
    end_time = serializers.DateField(required=False, allow_null=True)
    outline_list = serializers.ListField(required=False, allow_null=True)
    elecrical_info_list = serializers.ListField(required=False, allow_null=True)

    def to_representation(self, instance):
        # customer_obj = instance.customer
        electricityuser_obj = instance.electricity_user
        # if not customer_obj:
        #     raise ValidationError("没有关联客户")
        if not electricityuser_obj:
            raise ValidationError("没有关联户号")
        else:
            ret = super(PowerStationSerializer,
                        self).to_representation(instance)
            # ret["customer"] = customer_obj.id
            ret["electricity_user"] = electricityuser_obj.number
            return ret

    class Meta:
        model = PowerStation
        fields = ('id', 'name', 'addr', 'electricity_user', 'operation_level',
                  'person', 'phone', 'file', 'status', 'inspections_number',
                  'inspection_time', 'inspection_type', 'service_team',
                  'customer', "end_time", "inspector_ids", "outline_list", "elecrical_info_list")

    def validate(self, attrs):
        addr = attrs['addr']
        service_team = attrs['service_team']
        inspection_type = attrs['inspection_type']
        if not addr:
            raise ValidationError('请输入地址')
        geocodes = AmapApi().geo(address=str(addr))['geocodes']
        if not len(geocodes):
            raise ValidationError('地址无效请修改')
        if not service_team:
            raise ValidationError('需要绑定服务班组')
        else:
            if isinstance(service_team, str):
                service_team = service_team.split(',')
        if inspection_type == 0 and len(service_team) != 1:
            raise ValidationError('月巡检电站只能绑定一个班组')
        for item in service_team:
            if not Team.objects.filter(deleted=False, id=item).exists():
                raise ValidationError("请输入有效的服务班组")
        if service_team:
            attrs['service_team'] = service_team[0]
            attrs['inspector_ids'] = service_team[0]
        else:
            attrs['service_team'] = None
            attrs['inspector_ids'] = None
        return attrs

    def create(self, validated_data):
        validated_data.pop("outline_list")
        validated_data.pop("elecrical_info_list")
        instance = super(PowerStationSerializer, self).create(validated_data)
        instance.service_enterprise = self.context.get("request").data.get(
            "enterprise")
        instance.start_time = datetime.datetime.now()
        instance.customer = instance.electricity_user.customer
        instance.save()
        return instance

    def update(self, instance, validated_data):
        outline_list = validated_data.pop("outline_list")
        elecrical_info_list = validated_data.pop("elecrical_info_list")
        instance = super(PowerStationSerializer, self).update(instance, validated_data)
        # 先解除该电站的所有出线侧绑定
        Outline.objects.filter(powerstation=instance).update(**{"powerstation": None})
        # 绑定新的出线侧
        Outline.objects.filter(id__in=outline_list).update(**{"powerstation": instance})
        # 先解除该电站的所有电源编号绑定
        ElectricalInfromation.objects.filter(powerstation=instance).update(**{"powerstation": None})
        # 绑定新的电源编号
        ElectricalInfromation.objects.filter(id__in=elecrical_info_list).update(**{"powerstation": instance})
        return instance


class PowerStationListSerializer(ModelSerializer):
    # customer = PrimaryKeyRelatedField(queryset=Customer.objects.all())
    electricity_user = PrimaryKeyRelatedField(
        queryset=ElectricityUser.objects.all())

    equipment_set = PrimaryKeyRelatedField(read_only=True, many=True)
    outline_set = PrimaryKeyRelatedField(read_only=True, many=True)

    def to_representation(self, instance):

        if instance.electricity_user is None:
            raise ValidationError("请绑定户号")
        # if instance.electricity_user.customer.service_staff is None:
        #     raise ValidationError("客户业务主体不能为空")
        try:
            service_staff = instance.electricity_user.customer.service_staff

            service_staff = service_staff.nickname if service_staff else None
        except Users.DoesNotExist:
            service_staff = None

        return {
            'id': instance.id,
            'customer': {
                "id": instance.electricity_user.customer.id,
                "name": instance.electricity_user.customer.name
            },
            'electricity_user': {
                "id": instance.electricity_user.id,
                "number": instance.electricity_user.number
            },
            'name': instance.name,
            'addr': instance.addr,
            'service_staff': service_staff,
            'inspections_number': instance.inspections_number,
            "end_time": instance.end_time
        }

    class Meta:
        model = PowerStation
        fields = ('id', 'customer', 'electricity_user', 'name',
                  'service_staff', 'inspections_number', 'addr', 'outline_set')


class PowerstationDetailSerializer(ModelSerializer):
    # customer = PrimaryKeyRelatedField(queryset=Customer.objects.all())
    electricity_user = PrimaryKeyRelatedField(
        queryset=ElectricityUser.objects.all())
    province = serializers.CharField(default=None)
    city = serializers.CharField(default=None)
    area = serializers.CharField(default=None)
    electricalinfromation_set = ElectricalInfromationSerializer(many=True)
    outline_set = OutlineSerializer(many=True)

    def to_representation(self, instance):

        # geocodes = AmapApi.geo(address=str(instance.addr))['geocodes']
        # if not len(geocodes):
        #     raise ValidationError('地址无效请修改')
        # province = geocodes[0]['province']
        # city = geocodes[0]['city']
        # area = geocodes[0]['district']
        # location = geocodes[0]['location'].split(",", 1)
        # instance.province = province
        # instance.city = city
        # instance.area = area
        ret = super().to_representation(instance)
        if instance.electricity_user:
            ret['electricity_user'] = {
                "id": instance.electricity_user.id,
                "number": instance.electricity_user.number,
                "voltage_level": instance.electricity_user.voltage_level,
                "ep_factor": instance.electricity_user.ep_factor,
                "is_md": instance.electricity_user.is_md
            }
        try:
            customer = instance.electricity_user.customer
        except Customer.DoesNotExist:
            customer = ''
        ret['customer'] = {"id": customer.id, "name": customer.name}
        # ret['province'] = province
        # ret['city'] = city
        # ret['area'] = area
        # ret['longitude'] = location[0]
        # ret['latitude'] = location[1]
        if instance.service_team is None:
            ret['service_team'] = ''
        else:
            service_team = instance.service_team.split(',')
            if len(service_team) == 0:
                ret['service_team'] = ''
            else:
                team = Team.objects.filter(deleted=False, id__in=service_team)
                if team.exists():
                    ret['service_team'] = [{
                        "id": x.id,
                        "name": x.name
                    } for x in team]
                else:
                    ret['service_team'] = ''
        return ret

    class Meta:
        model = PowerStation
        fields = ('id', 'name', 'addr', 'province', 'city', 'area', 'customer',
                  'electricity_user', 'operation_level', 'person', 'phone',
                  'file', 'status', 'inspections_number', 'total_capacity',
                  'real_capacity', 'electricalinfromation_set', 'outline_set',
                  'inspection_time', 'inspection_type', 'service_team',
                  "end_time")


class CircuitsSerializer(ModelSerializer):
    class Meta:
        model = Circuit
        fields = ("id", "draw", "power_station_id")

    def to_representation(self, instance):
        instance.draw = (pickle.loads(zlib.decompress(eval(instance.draw)))
                         if instance.draw else None)
        return instance.to_dict()

    def validate(self, attrs):
        draw = attrs.get("draw")
        try:
            attrs["draw"] = str(zlib.compress(
                pickle.dumps(draw))) if draw else None
        except Exception as e:
            print(e)
            raise ValidationError("一次线路图数据非法")
        return attrs

    def to_internal_value(self, data):
        return data
