import json

from django_filters.rest_framework import DjangoFilterBackend
from openpyxl import Workbook, load_workbook
from rest_framework import status
from rest_framework.decorators import action, permission_classes
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.generics import GenericAPIView
from rest_framework.permissions import IsAdminUser, IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet
from rest_framework_jwt.authentication import JSONWebTokenAuthentication

from crm.models import Consumer, PaySubject
from examtest.models import WorkScope
from server import settings
from utils.custom import CommonPagination
from .exports import export_question


from .models import Question, Questioncat
from .serializers import (QuestioncatSerializer, QuestioncatSerializerDefault,
                          QuestionSerializer, SubjectSerializer)


class SubjectViewSet(ModelViewSet):
    """
    学科分类：增删改查
    """
    perms_map = (
        {'get': 'subject_view'}, {'post': 'subject_create'},
        {'put': 'subject_update'}, {'delete': 'subject_delete'})
    queryset = Questioncat.objects.filter(is_subject=True,is_delete=0).all().order_by("id")
    serializer_class = SubjectSerializer
    pagination_class = None
    ordering_fields = ('id',)
    ordering = ['id']
    search_fields = ('^name',)
    

class QuestioncatViewSet(ModelViewSet):
    """
    题库分类：增删改查
    """
    perms_map = (
        {'get': 'questioncat_view'}, {'post': 'questioncat_create'},
        {'put': 'questioncat_update'}, {'delete': 'questioncat_delete'})
    queryset = Questioncat.objects.filter(is_delete=0,is_subject=False).all()
    serializer_class = QuestioncatSerializerDefault
    pagination_class = CommonPagination
    ordering_fields = ['id']
    ordering = ['type','id']
    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    filterset_fields = ['pid']
    search_fields = ['name']

    @action(methods=['get'], detail=False,
            url_path='all', url_name='all_questioncat')
    def all(self, request):
        """
        题库分类全,不分页
        """
        queryset = Questioncat.objects.filter(is_delete=0).all()
        if request.query_params.get('pid',None):
            queryset = queryset.filter(pid = request.query_params.get('pid'))
        serializer = QuestioncatSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    
    @action(methods=['get'], detail=False,
            url_path='subject', url_name='questioncat_subject', pagination_class = None, permission_classes=[])
    def subject(self, request):
        """
        学科下的全部分类
        """
        queryset = Questioncat.objects.filter(is_delete=0, pid=request.query_params.get('id')).all()
        serializer = QuestioncatSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    
    @action(methods=['get'], detail=False,
            url_path='workscope', url_name='questioncat_workscope', pagination_class = None, permission_classes=[])
    def workscope(self, request):
        """
        工作类别下的全部分类
        """
        queryset = WorkScope.objects.get(id=request.query_params.get('id')).questioncat.all().order_by('pk')
        serializer = QuestioncatSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    
from django.db.models import Q
class QuestionViewSet(ModelViewSet):
    """
    题目：增删改查
    """
    perms_map = (
        {'get': 'question_view'}, {'post': 'question_create'},
        {'put': 'question_update'}, {'delete': 'question_delete'})
    queryset = Question.objects.filter(is_delete=0).all()
    serializer_class = QuestionSerializer
    pagination_class = CommonPagination
    ordering_fields = ['id', 'name']
    ordering = ['-create_time']
    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    filterset_fields = ['questioncat','level', 'type']
    search_fields = ['name', 'options', 'resolution']

    @action(methods=['post'], detail=False,
            url_path='count', url_name='question_count')
    def count(self, request):
        ret = {'danxuan':0,'duoxuan':0,'panduan':0}
        queryset = self.queryset
        if request.data.get('ids',None):
            queryset = queryset.filter(questioncat__in = request.data.get('ids'))
            ret['danxuan'] = queryset.filter(type='单选').count()
            ret['duoxuan'] = queryset.filter(type='多选').count()
            ret['panduan'] = queryset.filter(type='判断').count()
        return Response(ret)
    
    def get_queryset(self):
        user = self.request.user
        if isinstance(user, Consumer):
            questioncats = user.workscope.questioncat.all()
            self.queryset = self.queryset.filter(questioncat__in = questioncats)
        return super().get_queryset()

    @action(methods=['get'], detail=False,
            url_path='export', url_name='export_question', perms_map=[{'*':'export_question'}])
    def export(self, request):
        queryset = self.filter_queryset(self.get_queryset())
        path = export_question(queryset)
        return Response({'path': path})
    
    @action(methods=['get'], detail=False,
            url_path='correct', url_name='correct_question', permission_classes=[IsAuthenticated])
    def correct(self, request):
        # for i in Question.objects.all():
        #     options = i.options
        #     for k in options:
        #         options[k] = str(options[k]).replace('<p>','').replace('</p>','')\
        #         .replace('&times;','×').replace('&beta;','β').replace('&alpha;','α')\
        #             .replace('&gamma;','γ').replace('&nbsp;',' ')
        #     i.options = options
        #     i.save()
        for i in Question.objects.filter(Q(options__A__contains='&mu;')|Q(options__B__contains='&mu;')|Q(options__C__contains='&mu;')|Q(options__D__contains='&mu;')|Q(options__E__contains='&mu;')|Q(options__F__contains='&mu;')):
            print(i)
            options = i.options
            for k in options:
                options[k] = str(options[k]).replace('&mu;','μ')
            i.options = options
            i.save()
        return Response()

    @action(methods=['post'], detail=False, perms_map=[{'*':'question_delete'}])
    def deletes(self, request):
        """
        批量删除
        """
        ids = request.data.get('ids', [])
        if request.user.is_superuser:
            Question.objects.filter(id__in=ids).update(is_delete=True)
            return Response()
        return Response({'error':'权限不足'})

    @action(methods=['post'], detail=False, url_name='enable_question', permission_classes=[IsAuthenticated])
    def enable(self, request):
        ids = request.data.get('ids',None)
        if ids:
            Question.objects.filter(pk__in=ids).update(enabled=True)
            return Response(status=status.HTTP_200_OK)

    @action(methods=['post'], detail=False,
            url_path='import', url_name='import_question',perms_map=[{'post':'question_import'}])
    def import_question(self, request):
        """
        导入题目
        """
        xlsxpath = request.data['path']
        fullpath = settings.BASE_DIR + xlsxpath
        wb = load_workbook(fullpath)
        sheet = wb.worksheets[0]
        qlist = ['A','B','C','D','E','F']
        leveldict = {'低':'低','中':'中','高':'高'}
        notinlist = []
        # 验证文件内容
        if sheet['a2'].value != '题目类型':
            return Response({"error":"类型列错误!"})
        if sheet['b2'].value != '分类':
            return Response({"error":"分类列错误!"})
        if sheet['c2'].value != '题目':
            return Response({"error":"题目列错误!"})
        questioncatdict = {}
        questioncats = Questioncat.objects.filter(is_delete=0)
        for i in questioncats:
            questioncatdict[i.name] = i.id
        i = 3
        while sheet['c'+str(i)].value:
            type = sheet['a'+str(i)].value.replace(' ', '')
            questioncat = sheet['b'+str(i)].value.replace(' ', '')
            name = sheet['c'+str(i)].value
            answer = {}
            if sheet['d'+str(i)].value:
                answer['A'] = sheet['d'+str(i)].value
            if sheet['e'+str(i)].value:
                answer['B'] = sheet['e'+str(i)].value
            if sheet['f'+str(i)].value:
                answer['C'] = sheet['f'+str(i)].value
            if sheet['g'+str(i)].value:
                answer['D'] = sheet['g'+str(i)].value
            if sheet['h'+str(i)].value:
                answer['E'] = sheet['h'+str(i)].value
            if sheet['i'+str(i)].value:
                answer['F'] = sheet['i'+str(i)].value
            right = sheet['j'+str(i)].value.replace(' ', '')
            resolution = sheet['k'+str(i)].value
            level = sheet['l'+str(i)].value
            if level:
                level = level.replace(' ', '')
            if questioncat not in questioncatdict:
                 return Response({"error":"不存在分类("+questioncat+")!请先新建"})
            else:
                cateobj = Questioncat.objects.get(id=questioncatdict[questioncat])
            if type == '单选':
                if Question.objects.filter(type='单选',name=name, is_delete=0, questioncat=cateobj).exists():
                    notinlist.append(i)
                else:
                    if right in ['A','B','C','D','E','F']:        
                        obj = Question()
                        obj.type = '单选'
                        obj.questioncat = cateobj
                        obj.name = name
                        obj.options=answer
                        obj.right = right
                        obj.resolution = resolution if resolution else ''
                        if level in leveldict:
                            obj.level = leveldict[level]
                        else:
                            obj.level = '低'
                        obj.save()
            elif type == '多选':
                right = list(right)
                if Question.objects.filter(type='多选', name=name, is_delete=0, questioncat=cateobj).exists():
                    notinlist.append(i)
                else:
                    if [False for c in right if c not in qlist]:
                        pass
                    else:
                        obj = Question()
                        obj.type = '多选'
                        obj.questioncat = cateobj
                        obj.name = name
                        obj.options=answer
                        obj.right = right
                        obj.resolution = resolution if resolution else ''
                        if level in leveldict:
                            obj.level = leveldict[level]
                        else:
                            obj.level = '低'
                        obj.save()
            elif type == '判断':
                if right == 'A' or right == '对' or right == '正确':
                    right = 'A'
                else:
                    right = 'B'
                if Question.objects.filter(type='判断',name=name, is_delete=0, questioncat=cateobj).exists():
                    notinlist.append(i)
                else:
                    obj = Question()
                    obj.type = '判断'
                    obj.questioncat = cateobj
                    obj.name = name
                    obj.options={'A':'对','B':'错'}
                    obj.right = right
                    obj.resolution = resolution if resolution else ''
                    if level in leveldict:
                        obj.level = leveldict[level]
                    else:
                        obj.level = '低'
                    obj.save()
            i = i +1
        return Response(status=status.HTTP_200_OK)

class ExerciseView(APIView):
    perms_map=[{'post':'exercise'}]
    def post(self, request):
        questioncat = request.data['questioncat']
        queryset = Question.objects.filter(is_delete=0,questioncat=questioncat,enabled=True).order_by('type','pk', 'name')
        if 'ydtms' in request.data and request.data['ydtms']:
            queryset = queryset.exclude(id__in = request.data['ydtms'])
        if 'ydtms_' in request.data and request.data['ydtms_']:
            consumer = request.user
            process = consumer.process
            process['cat'+str(questioncat)] = request.data['ydtms_']
            consumer.process = process
            consumer.save()
        count = queryset.count()
        pg = CommonPagination()
        p = pg.paginate_queryset(queryset=queryset,request=request,view=self)
        serializer = QuestionSerializer(instance=p,many=True)
        collects = request.user.collects.all().values_list('id',flat=True) #当前用户收藏的题目
        results = serializer.data
        for i in results:
            if i['id'] in collects:
                i['is_collect'] = True
            else:
                i['is_collect'] = False
        return Response({'count':count, 'results':results})
