from apps.qm.models import QuaStat, TestItem, Ftest, FtestItem, FtestWork, Ptest
from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE
from apps.utils.serializers import CustomModelSerializer
from rest_framework import serializers
from apps.system.models import Dept, Dictionary
from apps.wpm.models import SfLog
from django.db import transaction


class TestItemSerializer(CustomModelSerializer):
    class Meta:
        model = TestItem
        fields = '__all__'
        read_only_fields = EXCLUDE_FIELDS


class QuaStatSerializer(CustomModelSerializer):
    sflog = serializers.PrimaryKeyRelatedField(
        label="值班记录", queryset=SfLog.objects.all(), required=True)
    belong_dept_name = serializers.CharField(
        source='belong_dept.name', read_only=True)
    material_name = serializers.CharField(
        source='material.name', read_only=True)
    testitem_name = serializers.CharField(
        source='testitem.name', read_only=True)

    class Meta:
        model = QuaStat
        fields = '__all__'
        read_only_fields = EXCLUDE_FIELDS + ['belong_dept']
        extra_kwargs = {'val_avg': {'required': True, 'allow_null': False}, 'num_test': {
            'required': True, 'allow_null': False}, 'num_ok': {'required': True, 'allow_null': False}}

    def validate(self, attrs):
        attrs['rate_pass'] = attrs['num_ok']/attrs['num_test']
        attrs['belong_dept'] = attrs['sflog'].mgroup.belong_dept
        return attrs


class QuaStatUpdateSerializer(CustomModelSerializer):
    belong_dept_name = serializers.CharField(
        source='belong_dept.name', read_only=True)
    material_name = serializers.CharField(
        source='material.name', read_only=True)
    testitem_name = serializers.CharField(
        source='testitem.name', read_only=True)

    class Meta:
        model = QuaStat
        fields = '__all__'
        read_only_fields = EXCLUDE_FIELDS + \
            ['belong_dept', 'sflog', 'material', 'testitem']
        extra_kwargs = {'val_avg': {'required': True, 'allow_null': False}, 'num_test': {
            'required': True, 'allow_null': False}, 'num_ok': {'required': True, 'allow_null': False}}

    def validate(self, attrs):
        attrs['rate_pass'] = attrs['num_ok']/attrs['num_test']
        return super().validate(attrs)


class FtestWorkCreateUpdateSerializer(CustomModelSerializer):
    class Meta:
        model = FtestWork
        fields = ['id', 'test_date', 'material', 'batch', 'count']


class FtestWorkSerializer(CustomModelSerializer):
    material_name = serializers.StringRelatedField(
        source='material', read_only=True)

    class Meta:
        model = FtestWork
        fields = "__all__"


class FtestItemSerializer(CustomModelSerializer):
    testitem_name = serializers.CharField(
        source='testitem.name', read_only=True)
    testitem_description = serializers.CharField(
        source='testitem.description', read_only=True)

    class Meta:
        model = FtestItem
        fields = '__all__'
        read_only_fields = EXCLUDE_FIELDS_BASE + ['ftest']


class FtestSerializer(CustomModelSerializer):
    test_user_name = serializers.CharField(
        source='test_user.name', read_only=True)
    check_user_name = serializers.CharField(
        source='check_user.name', read_only=True)
    ftestitems = FtestItemSerializer(label='检验明细', many=True)

    class Meta:
        model = Ftest
        fields = '__all__'
        read_only_fields = EXCLUDE_FIELDS + ['type']

    def validate(self, attrs):
        ftest_work = attrs.get('ftest_work', None)
        if ftest_work:
            attrs['type'] = 'prod'  # 带检验工作的标记为成品检验
        return attrs

    def create(self, validated_data):
        ftestitems = validated_data.pop('ftestitems', [])
        with transaction.atomic():
            instance = super().create(validated_data)
            for item in ftestitems:
                FtestItem.objects.create(ftest=instance, **item)
        return instance

    def update(self, instance, validated_data):
        validated_data.pop('ftest_work', None)
        ftestitems = validated_data.pop('ftestitems', [])
        with transaction.atomic():
            instance = super().update(instance, validated_data)
            for item in ftestitems:
                id = item.get('id', None)
                if id:
                    ftestitem = FtestItem.objects.get(id=id)
                    ftestitem.test_val = item['test_val']
                    ftestitem.check_val = item['check_val']
                    ftestitem.save()
        return instance


class PtestSerializer(CustomModelSerializer):
    testitem_name = serializers.CharField(
        source='testitem.name', read_only=True)

    class Meta:
        model = Ptest
        fields = '__all__'
