
from apps.hrm.models import Employee
from apps.rpm.models import Rcertificate, Remployee, Rfile, Rparty, Rpjcertificate, Rpjfile, Rpjmember, Rpj, BlackList
from apps.system.models import Dept
from apps.system.services import sync_dahua_dept
from apps.utils.constants import EXCLUDE_FIELDS
from apps.utils.fields import MyFilePathField
from apps.utils.serializers import CustomModelSerializer
from apps.system.serializers import DictSerializer, DictSimpleSerializer, FileSerializer, UserSimpleSerializer
from rest_framework import serializers
from rest_framework.exceptions import ParseError, ValidationError
from django.db import transaction
from apps.third.dahua import dhClient
from apps.third.tapis import dhapis
from apps.utils.tools import check_id_number_strict, check_phone_e
from apps.wf.serializers import TicketSimpleSerializer
from apps.rpm.services import rpj_member_come, rpj_certificate_in
from apps.rpm.models import RpjLog
from django.conf import settings
from django.db.models import Q


class RpartyCreateUpdateSerializer(CustomModelSerializer):
    class Meta:
        model = Rparty
        fields = ['name', 'number', 'lawer', 'contacter', 'phone', 'email',
                  'description', 'belong_dept', 'address']
        extra_kwargs = {
            'belong_dept': {'required': True}
        }

    @transaction.atomic
    def create(self, validated_data):
        if BlackList.objects.filter(Q(name=validated_data['name'])|Q(number=validated_data['number'])).exists():
            raise ParseError('该相关方在黑名单中')
        dept = Dept()
        dept.name = validated_data['name']
        dept.parent = validated_data['belong_dept']
        dept.type = 'rparty'
        dept.save()
        sync_dahua_dept(dept)
        validated_data['dept'] = dept
        return super().create(validated_data)

    @transaction.atomic
    def update(self, instance, validated_data):
        instance = super().update(instance, validated_data)
        dept = instance.dept
        if dept:
            dept.name = instance.name
            dept.is_deleted = False
            dept.parent = instance.belong_dept  # 重新规划归属部门
            dept.save()
            sync_dahua_dept(dept)
        return instance


class RpartySerializer(CustomModelSerializer):
    admin_ = UserSimpleSerializer(source='admin', read_only=True)
    belong_dept_name = serializers.CharField(source='belong_dept.name', read_only=True)

    class Meta:
        model = Rparty
        fields = '__all__'


class RpartySimpleSerializer(CustomModelSerializer):
    class Meta:
        model = Rparty
        fields = ['id', 'name']


class RpartyAssignSerializer(serializers.ModelSerializer):
    name = serializers.CharField(label="姓名")
    phone = serializers.CharField(label="手机号")
    username = serializers.CharField(label="账号")

    class Meta:
        model = Rparty
        fields = ['admin', 'name', 'phone', 'username']


class RfileListSerializer(CustomModelSerializer):
    rparty_ = RpartySimpleSerializer(source='rparty', read_only=True)
    file_cate_ = DictSerializer(source='file_cate', read_only=True)
    files_ = FileSerializer(source='files', many=True, read_only=True)

    class Meta:
        model = Rfile
        fields = '__all__'

class RpjUpdateSerializer(CustomModelSerializer):
    class Meta:
        model = Rpj
        fields = ['id', 'name', 'contract_number', 'type', 'come_time', 'leave_time', 'belong_dept', 'rparty']


class RpjCreateSerializer(RpjUpdateSerializer):
    rparty = serializers.PrimaryKeyRelatedField(queryset=Rparty.objects.all(), required=False, allow_null=True)
    belong_dept = serializers.PrimaryKeyRelatedField(queryset=Dept.objects.all(), required=False, allow_null=True)


class RpjListSerializer(CustomModelSerializer):
    rparty_name = serializers.CharField(source='rparty.name', read_only=True)
    belong_dept_name = serializers.CharField(source='belong_dept.name', read_only=True)
    create_by_name = serializers.CharField(source='create_by.name', read_only=True)
    ticket_ = TicketSimpleSerializer(source='ticket', read_only=True)

    class Meta:
        model = Rpj
        fields = '__all__'


# class RemployeeCreateSerializer(CustomModelSerializer):
#     phone = serializers.CharField(label="手机号", validators=[])
#     rparty = serializers.PrimaryKeyRelatedField(queryset=Rparty.objects.all(), label='相关方ID', required=False)

#     class Meta:
#         model = Remployee
#         fields = ['name', 'phone', 'photo', 'id_number', 'rparty']
#         # model = Employee
#         # exclude = EXCLUDE_FIELDS + ['is_atwork', 'last_check_time',
#         #                             'not_work_remark', 'third_info', 'type']
#         # extra_kwargs = {
#         #     'phone': {'required': True},
#         #     'number': {'required': True},
#         #     'photo': {'required': True},
#         #     'id_number': {'required': True},
#         # }

#     def create(self, validated_data):
#         with transaction.atomic():
#             # 校验上传的证件照
#             dhClient.request(**dhapis['person_img_upload'], file_path_rela=validated_data['photo'])
#             return super().create(validated_data)

class RemployeeCreateSerializer(CustomModelSerializer):
    rparty = serializers.PrimaryKeyRelatedField(queryset=Rparty.objects.all(), label='相关方ID', required=False)
    phone = serializers.CharField(label="手机号", validators=[check_phone_e])
    photo = serializers.CharField(label='照片地址', required=True)
    id_number = serializers.CharField(label="身份证号", validators=[check_id_number_strict], required=True)

    class Meta:
        model = Remployee
        fields = ['name', 'phone', 'photo', 'id_number', 'rparty']

    def create(self, validated_data):
        if Remployee.objects.filter(id_number=validated_data['id_number'], rparty=validated_data['rparty']).exists():
            raise ValidationError('该成员已存在')
        with transaction.atomic():
            if getattr(settings, 'DAHUA_ENABLED', False):
                dhClient.request(**dhapis['person_img_upload'], file_path_rela=validated_data['photo'])
            return super().create(validated_data)


class RemployeeUpdateSerializer(CustomModelSerializer):

    class Meta:
        model = Remployee
        fields = ['phone', 'photo', 'id_number']

    def update(self, instance, validated_data):
        with transaction.atomic():
            if getattr(settings, 'DAHUA_ENABLED', False):
                dhClient.request(**dhapis['person_img_upload'], file_path_rela=validated_data['photo'])
            return super().update(instance, validated_data)

class RemployeeSimpleSerializer(CustomModelSerializer):
    class Meta:
        model = Remployee
        fields = ['id', 'name', 'photo', 'id_number']


class RemployeeSerializer(CustomModelSerializer):
    rparty_name = serializers.CharField(source='rparty.name', read_only=True)
    photo_f = MyFilePathField(source='photo', read_only=True)
    blt_ = serializers.SerializerMethodField()

    class Meta:
        model = Remployee
        fields = '__all__'

    def get_blt_(self, obj):
        from apps.third.serializers import TDeviceSimpleSerializer
        ep = obj.employee
        if ep and hasattr(ep, 'tdevice'):
            return TDeviceSimpleSerializer(instance=ep.tdevice).data


class RcertificateCreateUpdateSerializer(CustomModelSerializer):
    class Meta:
        model = Rcertificate
        exclude = EXCLUDE_FIELDS + ['certificate']


class RcertificateSerializer(CustomModelSerializer):
    remployee_name = serializers.CharField(source='remployee.name', read_only=True)
    rparty_name = serializers.CharField(source='rparty.name', read_only=True)
    file_f = MyFilePathField(source='file', read_only=True)

    class Meta:
        model = Rcertificate
        fields = '__all__'


class RpjmemberCreatesSerializer(CustomModelSerializer):
    employees = serializers.PrimaryKeyRelatedField(
        queryset=Employee.objects.filter(type='remployee'),
        many=True, label='员工ID列表'
    )

    class Meta:
        model = Rpjmember
        fields = ['employees', 'Rpj']


class RpjmemberCreateSerializer(CustomModelSerializer):
    rcertificates = serializers.PrimaryKeyRelatedField(label='证书ID', many=True, queryset=Rcertificate.objects.all())
    reason = serializers.CharField(label='后入厂原因', required=False, allow_blank=True) 
    class Meta:
        model = Rpjmember
        fields = ['remployee', 'rpj', 'duty', 'is_manager', 'rcertificates', 'reason']

    def create(self, validated_data):
        rpj = validated_data['rpj']
        if rpj.state in [Rpj.RPJ_DONE, Rpj.RPJ_CLOSE]:
            raise ParseError('该项目状态成员不可新增')
        rcertificates = validated_data.pop('rcertificates')
        remployee = validated_data['remployee']
        if remployee.phone and remployee.photo and remployee.id_number:
            pass
        else:
            raise ParseError('该成员信息不全请补充')
        re_in = False
        rpjm = Rpjmember.objects.filter(remployee=remployee, rpj=validated_data['rpj']).first()
        if rpjm is None:
            pass
        elif rpjm and rpjm.note == '提前离厂':
            re_in = True
        else:
            raise ParseError('该成员已添加')
        with transaction.atomic():
            reason = validated_data.pop('reason', '')
            if re_in:
                ins = super().update(rpjm, validated_data)
            else:
                ins = super().create(validated_data)
            for x in rcertificates:
                rpjc = Rpjcertificate.objects.filter(rpj_member=ins, rcertificate=x).first()
                if rpjc:
                    pass
                else:
                    rpjc = Rpjcertificate()
                    rpjc.rpj_member = ins
                    rpjc.rcertificate = x
                # for i in ['name', 'number', 'type', 'issue_date', 'expiration_date', 'review_date', 'file']:
                for f in Rcertificate._meta.fields:
                    if f.name not in ['id']:
                        setattr(rpjc, f.name, getattr(x, f.name, None))
                rpjc.save()
            if ins.is_manager:
                Rpjmember.objects.exclude(id=ins.id).update(is_manager=False)
        if rpj.state in [Rpj.RPJ_ENTER, Rpj.RPJ_WORKING]: # 如果是待入厂后添加的
            # 需要执行入厂操作
            try:
                rpj_member_come(ins)
                rpj_certificate_in(ins)
                ins.note = '后入厂'
                if re_in:
                    ins.note = '重新入厂'
                ins.save()
            except Exception:
                if not re_in:
                    ins.delete()
                raise
            RpjLog.objects.create(rpj=rpj, operation='member_come', remployee=remployee, create_by=self.context['request'].user, reason=reason)
        return ins


class RpjmemberUpdateSerializer(CustomModelSerializer):
    rcertificates = serializers.PrimaryKeyRelatedField(label='证书ID', many=True, queryset=Rcertificate.objects.all())

    class Meta:
        model = Rpjmember
        fields = ['duty', 'is_manager', 'rcertificates']

    def update(self, instance, validated_data):
        rpj = instance.rpj
        if rpj.state in [Rpj.RPJ_DONE, Rpj.RPJ_CLOSE]:
            raise ParseError('该项目状态成员不可修改')
        rcertificates = validated_data.pop('rcertificates')
        with transaction.atomic():
            ins = super().update(instance, validated_data)
            for x in rcertificates:
                rpjc = Rpjcertificate.objects.filter(rpj_member=ins, rcertificate=x).first()
                if rpjc:
                    pass
                else:
                    rpjc = Rpjcertificate()
                    rpjc.rpj_member = ins
                    rpjc.rcertificate = x
                for f in Rcertificate._meta.fields:
                    if f.name not in ['id']:
                        setattr(rpjc, f.name, getattr(x, f.name, None))
                rpjc.save()
            if ins.is_manager:
                Rpjmember.objects.exclude(id=ins.id).update(is_manager=False)
            if rpj.state in [Rpj.RPJ_ENTER, Rpj.RPJ_WORKING]: # 如果是待入厂后更改的
                rpj_certificate_in(ins)
        return ins

class RpjLogSerializer(CustomModelSerializer):
    remployee_ = RemployeeSimpleSerializer(source='remployee', read_only=True)
    create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
    class Meta:
        model = RpjLog
        fields = '__all__'

class RpjcertificateSerializer(CustomModelSerializer):
    file_f = MyFilePathField(source='file', read_only=True)

    class Meta:
        model = Rpjcertificate
        fields = ['rcertificate', 'name', 'type', 'number', 'issue_date',
                  'expiration_date', 'review_date', 'file', 'file_f']


class RpjmemberSerializer(CustomModelSerializer):
    remployee_ = RemployeeSerializer(source='remployee', read_only=True)
    rcertificates_ = serializers.SerializerMethodField()

    class Meta:
        model = Rpjmember
        fields = '__all__'

    def get_rcertificates_(self, obj):
        cs = Rpjcertificate.objects.filter(rpj_member=obj)
        return RpjcertificateSerializer(instance=cs, many=True).data


class RpjfileSerializer(CustomModelSerializer):
    file_cate_ = DictSimpleSerializer(source='file_cate', read_only=True)
    files_ = FileSerializer(source='files', read_only=True, many=True)

    class Meta:
        model = Rpjfile
        fields = '__all__'


class RpjfileUpdateSerializer(CustomModelSerializer):
    class Meta:
        model = Rpjfile
        fields = ['files']


class BlackListCreateSerializer(CustomModelSerializer):
    class Meta:
        model = BlackList
        fields = ['name', 'number', 'reason']


class BlackListUpdateSerializer(CustomModelSerializer):
    class Meta:
        model = BlackList
        fields = ['reason']


class BlackListSerializer(CustomModelSerializer):
    create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
    update_by_ = UserSimpleSerializer(source='update_by', read_only=True)

    class Meta:
        model = BlackList
        fields = '__all__'