from rest_framework import serializers
from question.models import Questioncat
from crm.models import Consumer
from .models import Exam, ExamTest, AnswerDetail, Banner
from .models_paper import TestRule, WorkScope, Paper, PaperQuestions
from question.serializers import QuestionSerializer

class BannerSerializer(serializers.ModelSerializer):
    """
    轮播图序列化
    """
    class Meta:
        model = Banner
        fields = ('id','name','path', 'url', 'sort')
class TestRuleSerializer(serializers.ModelSerializer):
    """
    规则序列化
    """
    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
    update_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
    class Meta:
        model = TestRule
        fields = '__all__'

class WorkScopeSerializer(serializers.ModelSerializer):
    """
    工作类别序列化
    """
    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
    update_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
    subject_name = serializers.StringRelatedField(source='subject',read_only=True)
    class Meta:
        model = WorkScope
        fields = '__all__'
    
    @staticmethod
    def setup_eager_loading(queryset):
        """ Perform necessary eager loading of data. """
        queryset = queryset.prefetch_related('questioncat',)
        return queryset

class MoniTestSerializer(serializers.ModelSerializer):
    """
    考试序列化
    """
    start_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
    end_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
    consumer = serializers.PrimaryKeyRelatedField(queryset=Consumer.objects.all(), required=False)
    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
    update_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
    class Meta:
        model = ExamTest
        fields = '__all__'


class ExamTestListSerializer(serializers.ModelSerializer):
    """
    考试列表序列化
    """
    start_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
    end_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
    workscope_name = serializers.StringRelatedField(source='workscope', read_only=True)
    paper_name = serializers.StringRelatedField(source='paper', read_only=True)
    exam_name = serializers.StringRelatedField(source='exam', read_only=True)
    consumer_name = serializers.SerializerMethodField()
    consumer_username = serializers.CharField(source='consumer.username', read_only=True)
    took_format = serializers.SerializerMethodField()
    consumer_company_name = serializers.SerializerMethodField()
    class Meta:
        model = ExamTest
        exclude = ('detail',)
    
    def get_consumer_name(self, obj):
        return obj.consumer.name 

    def get_took_format(self, obj):
        m, s = divmod(obj.took, 60)
        h, m = divmod(m, 60)
        return "%02d:%02d:%02d" % (h, m, s)
    
    def get_consumer_company_name(self, obj):
        if obj.consumer.company:
            return obj.consumer.company.name
    
    @staticmethod
    def setup_eager_loading(queryset):
        """ Perform necessary eager loading of data. """
        queryset = queryset.select_related('consumer','paper', 'workscope', 'exam')
        return queryset
from question.serializers import QuestionSerializer
class AnswerDetailSerializer(serializers.ModelSerializer):
    question = QuestionSerializer()
    class Meta:
        model = AnswerDetail
        exclude = ('examtest',)
        # fields = '__all__'

    @staticmethod
    def setup_eager_loading(queryset):
        """ Perform necessary eager loading of data. """
        # select_related for "to-one" relationships
        queryset = queryset.select_related('examtest',)

        # prefetch_related for "to-many" relationships
        queryset = queryset.prefetch_related(
            'question',)

        # Prefetch for subsets of relationships
        # queryset = queryset.prefetch_related(
        #     Prefetch('unaffiliated_attendees', 
        #         queryset=Attendee.objects.filter(organization__isnull=True))
        #     )
        return queryset

class AnswerDetailCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = AnswerDetail
        fields = '__all__'

class PaperSerializer(serializers.ModelSerializer):
    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
    update_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
    workscope_name = serializers.StringRelatedField(source='workscope', read_only=True)
    class Meta:
        model = Paper
        exclude = ('questions',)


class PaperQuestionsDetailSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(source='question.id')
    name = serializers.ReadOnlyField(source='question.name')
    options = serializers.ReadOnlyField(source='question.options')
    right = serializers.ReadOnlyField(source='question.right')
    type = serializers.ReadOnlyField(source='question.type')
    img = serializers.ReadOnlyField(source='question.img')
    questioncat_name = serializers.ReadOnlyField(source='question.questioncat.name')
    level = serializers.ReadOnlyField(source='question.level')
    class Meta:
        model = PaperQuestions
        fields = ('id','name','options','right','type','level','total_score','questioncat_name', 'img')

    @staticmethod
    def setup_eager_loading(queryset):
        """ Perform necessary eager loading of data. """
        queryset = queryset.prefetch_related('question',)
        return queryset

class PaperDetailSerializer(serializers.ModelSerializer):
    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
    update_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
    workscope_name = serializers.StringRelatedField(source='workscope', read_only=True)
    questions = serializers.SerializerMethodField()
    class Meta:
        model = Paper
        fields = '__all__'
    
    def get_questions(self, instance):
        queryset = PaperQuestions.objects.filter(paper=instance).order_by('question__type')
        queryset = PaperQuestionsDetailSerializer.setup_eager_loading(queryset)
        return PaperQuestionsDetailSerializer(queryset, many=True).data
    

class PaperQuestionsCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = PaperQuestions
        fields = '__all__'

class ExamCreateUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Exam
        fields = ['name', 'place', 'opentime', 'closetime', 'proctor_name', 'proctor_phone', 'workscope', 'chance', 
                    'train_name', 'train_start_date', 'train_end_date', 'paper']

class ExamListSerializer(serializers.ModelSerializer):
    create_admin_username = serializers.StringRelatedField(source='create_admin')
    workscope_name = serializers.StringRelatedField(source='workscope')
    class Meta:
        model = Exam
        fields = '__all__'
    
    @staticmethod
    def setup_eager_loading(queryset):
        """ Perform necessary eager loading of data. """
        queryset = queryset.prefetch_related('workscope','create_admin')
        return queryset

class ExamSimpleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Exam
        exclude = ('create_admin',)

class ConsumerSimpleSerializer(serializers.ModelSerializer):
    comanyname = serializers.StringRelatedField(source='company', read_only=True)
    class Meta:
        model = Consumer
        fields = ['id', 'name', 'ID_number1', 'comanyname', 'deptname', 'username']
        
class ExamTestDetailSerializer(serializers.ModelSerializer):
    """
    考试详情序列化(导出用);目前是正式考试,用户详情从consumer_detail获取
    """
    workscope_name = serializers.StringRelatedField(source='workscope', read_only=True)
    paper_name = serializers.StringRelatedField(source='paper', )
    took_format = serializers.SerializerMethodField()
    detail_ = serializers.SerializerMethodField()
    exam_ = ExamSimpleSerializer(source='exam', read_only=True)
    consumer_ = ConsumerSimpleSerializer(source='consumer', read_only=True)

    class Meta:
        model = ExamTest
        exclude = ('detail',)

    def get_took_format(self, obj):
        m, s = divmod(obj.took, 60)
        h, m = divmod(m, 60)
        return "%02d:%02d:%02d" % (h, m, s)

    def get_detail_(self, obj):
        objs = obj.answerdetail_examtest.order_by('question__type')
        return AnswerDetailSerializer(instance=objs, many=True).data
    
    @staticmethod
    def setup_eager_loading(queryset):
        """ Perform necessary eager loading of data. """
        queryset = queryset.select_related('consumer','paper', 'workscope', 'exam')
        queryset = queryset.prefetch_related('answerdetail_examtest')
        return queryset



class ExamTestExamListSerializer(serializers.ModelSerializer):
    """
    正式考试列表序列化
    """
    start_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
    end_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
    workscope_name = serializers.StringRelatedField(source='workscope', read_only=True)
    took_format = serializers.SerializerMethodField()
    candidate_ = serializers.SerializerMethodField()
    exam_name = serializers.StringRelatedField(source='exam', read_only=True)

    class Meta:
        model = ExamTest
        exclude = ('detail',)

    def get_took_format(self, obj):
        m, s = divmod(obj.took, 60)
        h, m = divmod(m, 60)
        return "%02d:%02d:%02d" % (h, m, s)
    
    def get_candidate_(self, obj):
        candidate = obj.candidate if hasattr(obj, 'candidate') else None
        if candidate:
            return {'id':obj.candidate.id, 'number':obj.candidate.number}
    @staticmethod
    def setup_eager_loading(queryset):
        """ Perform necessary eager loading of data. """
        queryset = queryset.select_related('candidate', 'consumer')
        return queryset