from django.db.models.base import Model
from rest_framework import serializers
from .models import *
from apps.system.serializers import OrganizationSerializer,FileListSerializer,UserSimpleSerializer,OrganizationSimpleSerializer, FileSimpleSerializer
from rest_framework.exceptions import ParseError
import datetime


class ContentSerializer(serializers.ModelSerializer):
    type_ = serializers.SerializerMethodField()
    class Meta:
        model = Content
        fields = '__all__'
    
    @staticmethod
    def setup_eager_loading(queryset):
        """ Perform necessary eager loading of data. """
        queryset = queryset.select_related('type')
        return queryset
    
    def get_type_ (self, obj):
        data = obj.type.name
        if obj.type.pid:
            data = obj.type.pid.name + '/' + data
        return data

class ContentListSerializer(serializers.ModelSerializer):
    class Meta:
        model = Content
        fields = ['name', 'desc', 'id', 'template']

class TaskCreateUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Task
        fields = ['name', 'end_date', 'note', 'id']

class TaskListSerializer(serializers.ModelSerializer):
    class Meta:
        model = Task
        fields = ['name', 'end_date', 'note', 'state', 'id']
        
class RecordSerializer(serializers.ModelSerializer):
    content_ = ContentListSerializer(source='content', read_only=True)
    task_ = TaskListSerializer(source='task', read_only=True)
    belong_dept_ = OrganizationSimpleSerializer(source='belong_dept', read_only=True)
    files_ = FileSimpleSerializer(source='files', many=True, read_only=True)
    up_user_ = UserSimpleSerializer(source='up_user', read_only = True)
    class Meta:
        model = Record
        fields = '__all__'
    
    @staticmethod
    def setup_eager_loading(queryset):
        queryset = queryset.select_related('task', 'content', 'belong_dept', 'up_user')
        queryset = queryset.prefetch_related('files',)
        return queryset

class RecordCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Record
        fields = ['content', 'files', 'noteb']


class TaksDetailSerializer(serializers.ModelSerializer):
    create_by_ = UserSimpleSerializer(source='create_by', read_only = True)
    belong_dept_ = OrganizationSimpleSerializer(source='belong_dept', read_only=True)
    class Meta:
        model = Task
        fields = '__all__'

class TaskDeptSerializer(serializers.ModelSerializer):
    task_ = TaskListSerializer(source='task', read_only=True)
    dept_ = OrganizationSimpleSerializer(source='dept', read_only=True)

    class Meta:
        model = TaskDept
        fields = '__all__'
    
    @staticmethod
    def setup_eager_loading(queryset):
        queryset = queryset.select_related('task', 'dept')
        return queryset
    

class PgoalCreateUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Pgoal
        fields = ['year', 'pgoal_1', 'pgoal_2', 'pgoal_3', 'pgoal_4', 'pgoal_5', 'pgoal_1_file', 'pgoal_2_file', 'pgoal_3_file', 'pgoal_4_file', 'pgoal_5_file']


class PgoalSerializer(serializers.ModelSerializer):
    pgoal_1_file_ = FileSimpleSerializer(source='pgoal_1_file', read_only=True)
    pgoal_2_file_ = FileSimpleSerializer(source='pgoal_2_file', read_only=True)
    pgoal_3_file_ = FileSimpleSerializer(source='pgoal_3_file', read_only=True)
    pgoal_4_file_ = FileSimpleSerializer(source='pgoal_4_file', read_only=True)
    pgoal_5_file_ = FileSimpleSerializer(source='pgoal_5_file', read_only=True)
    class Meta:
        model = Pgoal
        fields = '__all__'


# class Task2CreateUpdateSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = Task2
#         fields = ['year', 'cycle', 'type']


class Task2Serializer(serializers.ModelSerializer):
    create_by_name = serializers.CharField(source='create_by.name', read_only=True)
    class Meta:
        model = Task2
        fields = '__all__'
        read_only_fields = ['create_time', 'update_time', 'create_by', 'update_by', 'belong_dept', 'state', 'is_deleted', 'depts']
    
    def update(self, instance, validated_data):
        validated_data.pop('type', None)  # type不可编辑
        if instance.state == Task2.TASK2_CLOSE:
            raise ParseError('已关闭不可编辑')
        return super().update(instance, validated_data)
    
class Task2DeptsSerializer(serializers.Serializer):
    ids = serializers.PrimaryKeyRelatedField(label="部门ID列表", many=True, queryset=Organization.objects.all())


class Task2DoSerializer(serializers.ModelSerializer):
    belong_dept_ = OrganizationSimpleSerializer(source='belong_dept', read_only=True)
    task2_ = Task2Serializer(source='task2', read_only=True)
    class Meta:
        model = Task2Do
        fields = '__all__'

class ValidateMixin:
    def validate(self, attrs):
        task2do = attrs.get('task2do', None)
        attrs['create_by'] = self.context['request'].user
        attrs['belong_dept'] = self.context['request'].user.dept
        if task2do:
            if task2do.task2.state == Task2.TASK2_CLOSE:
                raise ParseError('任务已关闭不可处理')
            attrs['belong_dept'] = task2do.belong_dept
        return attrs

class BaseMeta:
    fields = '__all__'
    read_only_fields = ['create_time', 'update_time', 'create_by', 'update_by', 'is_deleted', 'belong_dept']
    
class PgoalDeptSerializer(serializers.ModelSerializer):
    goal_file_ = FileSimpleSerializer(source='goal_file', read_only=True)
    goal_files_ = FileSimpleSerializer(source='goal_files', many=True, read_only=True)
    belong_dept_name = serializers.CharField(source='belong_dept.name', read_only=True)
    class Meta(BaseMeta):
        model = PgoalDept
        read_only_fields = BaseMeta.read_only_fields + ['goal_value_a', 'goal_value_c', 'goal_files', 'goal_key', 'goal_file_', 'goal_files_']

    def validate(self, attrs):
        task2do = attrs.get('task2do', None)
        attrs['create_by'] = self.context['request'].user
        attrs['belong_dept'] = self.context['request'].user.dept
        if task2do:
            if task2do.task2.state == Task2.TASK2_CLOSE:
                raise ParseError('任务已关闭不可处理')
            attrs['year'] = task2do.task2.year
            attrs['belong_dept'] = task2do.belong_dept
        return attrs

class DateField(serializers.Field):
    def to_internal_value(self, value):
        if isinstance(value, datetime.datetime):
            return value
        elif isinstance(value, datetime.date):
            return value
        try:
            date_obj = datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S').date()
        except ValueError:
            try:
                date_obj = datetime.datetime.strptime(value, '%Y-%m-%d').date()
            except ValueError:
                raise serializers.ValidationError("日期格式错误")
        return date_obj
    
    def to_representation(self, value):
        if isinstance(value, datetime.date):
            value = value.strftime('%Y-%m-%d')
        return super().to_representation(value)
    
class RcSerializer(ValidateMixin, serializers.ModelSerializer):
    # date_issue = DateField(required=False, allow_null=True)
    # date_accept = DateField(required=False, allow_null=True)
    # date_expect = DateField(required=False, allow_null=True)
    class Meta(BaseMeta):
        model = Rc


class ComplaintSerializer(ValidateMixin, serializers.ModelSerializer):

    # date_occurrence = DateField()
    # date_feedback = DateField()
    class Meta(BaseMeta):
        model = Complaint

class PtSerializer(ValidateMixin, serializers.ModelSerializer):

    class Meta(BaseMeta):
        model = Pt

class RiskSerializer(ValidateMixin, serializers.ModelSerializer):

    class Meta(BaseMeta):
        model = Risk

class OinspectSerializer(ValidateMixin, serializers.ModelSerializer):
    # date_inspect = DateField()
    class Meta(BaseMeta):
        model = Oinspect


class NoRecordSerializer(serializers.Serializer):
    key = serializers.ChoiceField(label='字段key', choices=['num_error', 'num_overdue', 'num_complaint', 'num_pt', 'num_risk', 'num_oinspect'])


class UpdateFieldSerializer(serializers.ModelSerializer):

    class Meta:
        model = Task2Do
        fields = ['num_issue', 'num_expect', 'num_acc']
        extra_kwargs = {'num_issue': {'required': True}, 'num_expect': {'required': True}, 'num_acc': {'required': True}}



class ImpSerializer(serializers.Serializer):
    path = serializers.CharField(label='文件地址')
    task2do = serializers.PrimaryKeyRelatedField(label='关联task2do的ID值', queryset = Task2Do.objects.all())