from rest_framework import serializers
from rest_framework.exceptions import ValidationError, ParseError
import math

from apps.mtm.serializers import MaterialSimpleSerializer
from apps.pm.models import Mtask, Utask
from apps.sam.models import OrderItem
from apps.utils.serializers import CustomModelSerializer
from apps.system.models import Dept
from apps.wpm.models import Mlog


class UtaskSerializer(CustomModelSerializer):
    material_name = serializers.StringRelatedField(
        source='material', read_only=True)
    material_in_name = serializers.StringRelatedField(
        source='material_in', read_only=True)
    material_ = MaterialSimpleSerializer(source='material', read_only=True)
    mgroup_name = serializers.CharField(source='mgroup.name', read_only=True)
    belong_dept = serializers.PrimaryKeyRelatedField(
        queryset=Dept.objects.all(), required=False)

    class Meta:
        model = Utask
        fields = '__all__'

    def validate(self, attrs):
        end_date = attrs['end_date']
        start_date = attrs['start_date']
        if 'mgroup' in attrs and attrs['mgroup']:
            attrs['belong_dept'] = attrs['mgroup'].belong_dept
        try:
            rela_days = (end_date - start_date).days + 1
            attrs['count_day'] = math.ceil(attrs['count']/rela_days)
        except Exception:
            raise ParseError('日均任务数计划失败')
        return attrs

    def update(self, instance, validated_data):
        if instance.state != Utask.UTASK_CREATED:
            raise ValidationError('任务非创建中不可编辑')
        new_data = {key: validated_data[key] for key in [
            'number', 'count', 'start_date', 'end_date']}
        return super().update(instance, new_data)


class MlogSimpleSerializer(CustomModelSerializer):
    shift_name = serializers.CharField(source='shift.name', read_only=True)

    class Meta:
        model = Mlog
        fields = ['id', 'shift_name', 'count_use',
                  'count_ok', 'count_real', 'submit_time']


class MtaskSerializer(CustomModelSerializer):
    material_out_ = MaterialSimpleSerializer(
        source='material_out', read_only=True)
    material_out_name = serializers.StringRelatedField(
        source='material_out', read_only=True)
    material_in_name = serializers.StringRelatedField(
        source='material_in', read_only=True)
    submit_user_name = serializers.StringRelatedField(
        source='submit_user.name', read_only=True)
    mgroup_name = serializers.CharField(source='mgroup.name', read_only=True)
    mlogs = MlogSimpleSerializer(label='日志信息', many=True, required=False)

    class Meta:
        model = Mtask
        fields = '__all__'
        read_only_fields = ['utask']

    def update(self, instance, validated_data):
        if instance.state != Mtask.MTASK_CREATED:
            raise ValidationError('任务非创建中不可编辑')
        if instance.utask is not None:
            new_data = {'count': validated_data['count']}
        else:
            new_data = {key: validated_data[key] for key in [
                'number', 'count', 'start_date', 'end_date']}
        return super().update(instance, new_data)


class SchedueSerializer(serializers.Serializer):
    orderitems = serializers.PrimaryKeyRelatedField(
        label='orderitem的ID列表', queryset=OrderItem.objects.all(), many=True)
    start_date = serializers.DateField(label='计划开工日期')
    end_date = serializers.DateField(label='计划完工日期')
    belong_dept = serializers.PrimaryKeyRelatedField(
        label='车间ID', queryset=Dept.objects.all(), required=False)


class MtaskDaySerializer(serializers.Serializer):
    belong_dept_name = serializers.CharField(label='车间名称')
    date = serializers.DateField(label='日期')


class MtaskAddInfoSerializer(CustomModelSerializer):
    class Meta:
        model = Mtask
        fields = ['peifen_kg']
