from django.db import transaction
from rest_framework.serializers import ModelSerializer, SerializerMethodField
from common.accounts.models import Users, UserEnterprise, Enterprise, UserRoles
from rest_framework.serializers import Serializer, ValidationError
from common.utils.service_code import PARAMETER_ERROR
from rest_framework import serializers
from console.customer.models import CustomerAdmin
from console.electricityuser.models import ElectricityUser


class FileUploadSerializers(serializers.Serializer):
    file = serializers.FileField(required=True, use_url=False)

    class Meta:
        fields = "file"


class CustInfoSerializer(ModelSerializer):
    name = SerializerMethodField()
    enterprise_name = SerializerMethodField()
    logo = SerializerMethodField()
    phone = SerializerMethodField()
    elecno = SerializerMethodField()
    adrr = SerializerMethodField()

    class Meta:
        model = CustomerAdmin
        fields = ('name', 'enterprise_name', 'logo', 'phone', 'elecno', 'adrr')

    def to_internal_value(self, data):
        return data

    def get_name(self, obj):
        return obj.user.nickname

    def get_enterprise_name(self, obj):
        return obj.customer.enterprise.name

    def get_logo(self, obj):
        return obj.customer.enterprise.logo

    def get_phone(self, obj):
        u = Users.objects.filter(id=obj.user.id)
        if not u:
            return ""
        return u.first().phone

    def get_elecno(self, obj):
        u = ElectricityUser.objects.filter(customer=obj.customer)
        res = []
        for x in u:
            if x.number is not None and x.number != '':
                res.append(str(x.number))
        return ','.join(res)

    def get_adrr(self, obj):
        return obj.customer.enterprise.address


class UserInfoSerializer(ModelSerializer):
    role = SerializerMethodField()
    custom_id = SerializerMethodField()
    name = SerializerMethodField()
    organization = SerializerMethodField()

    class Meta:
        model = Users
        fields = ('custom_id', 'name', 'role', 'phone', 'email',
                  'organization')

    def to_internal_value(self, data):
        return data

    def get_custom_id(self, obj):
        return obj.id

    def get_role(self, obj):
        ur = UserRoles.objects.filter(user_id=obj.id)
        if not ur:
            return None
        ur_role = []
        for i in ur:
            if i.role:
                ur_role.append(i.role.name)
        res = ','.join(ur_role)
        return res

    def get_name(self, obj):
        return obj.nickname

    def get_organization(self, obj):
        ue = UserEnterprise.objects.filter(user_id=obj.id).first()
        if ue:
            return Enterprise.objects.filter(
                enterprise_id=ue.enterprise_id).first().name
        else:
            return None


class MiniUserInfoSerializer(ModelSerializer):
    name = SerializerMethodField()
    logo = SerializerMethodField()
    enterprise_id = SerializerMethodField()
    enterprise_name = SerializerMethodField()
    phone = SerializerMethodField()
    customer_id = SerializerMethodField()

    class Meta:
        model = UserEnterprise
        fields = ('name', 'logo', 'enterprise_id', 'enterprise_name', 'phone',
                  'customer_id')

    def to_internal_value(self, data):
        return data

    def get_name(self, obj):
        return obj.user.nickname

    def get_logo(self, obj):
        return obj.enterprise.logo

    def get_enterprise_id(self, obj):
        return obj.enterprise.id

    def get_enterprise_name(self, obj):
        return obj.enterprise.name

    def get_phone(self, obj):
        return obj.user.phone

    def get_customer_id(self, obj):
        customer_user = CustomerAdmin.objects.filter(user=obj.user,
                                                     deleted=False).first()
        try:
            return customer_user.customer.id
        except Exception:
            return None


class UserDeleteSerializer(Serializer):
    def validate(self, attrs):
        if not isinstance(attrs, str):
            raise ValidationError("参数数据类型不对，应为str", code=PARAMETER_ERROR)
        return attrs


class AccountUpdateSerializer(Serializer):
    head_img = serializers.CharField(required=False,
                                     allow_null=True,
                                     help_text="头像",
                                     allow_blank=True)
    nickname = serializers.CharField(required=False,
                                     allow_null=True,
                                     allow_blank=True,
                                     help_text="地址")
    phone = serializers.CharField(required=False,
                                  allow_null=True,
                                  allow_blank=True,
                                  help_text="电话号码")
    password = serializers.CharField(required=False,
                                     allow_blank=True,
                                     allow_null=True,
                                     help_text="密码")

    @transaction.atomic()
    def update(self, instance, validated_data):
        point = transaction.savepoint()
        try:
            instance.head_img = validated_data.get("head_img")
            if validated_data.get("password"):
                instance.set_password(validated_data.get("password"))
            instance.save()
            user = Users.objects.filter(account=instance).first()
            user.phone = validated_data.get("phone")
            user.nickname = validated_data.get("nickname")
            user.save()
            transaction.savepoint_commit(point)
            return instance
        except Exception as e:
            transaction.savepoint_rollback(point)
            raise serializers.ValidationError(e)


class AccountUpdateHeadImageSerializer(Serializer):
    url = serializers.CharField(required=True,
                                help_text="图片url",
                                allow_null=False,
                                allow_blank=False)

    def update(self, instance, validated_data):
        instance.head_img = validated_data.get("url")
        instance.save()
        return instance
