from datetime import timedelta
from time import timezone
from apps.system.models import Dict
from rest_framework.mixins import ListModelMixin, UpdateModelMixin
from apps.vod.serializers import VRecordSerializer, VRecordUpdateSerializer, VideoListDetailSerializer, VideoSerializer, VideoUpdateSerializer, ViewItemSerializer, ViewItemUpdateSerializer, View2Serializer, DatetimeSerializer
from apps.vod.models import Video, ViewRecord, ViewItem, View1, View2
from django.shortcuts import render
from .vodclient import getAllClass, getPlayCode, searchMedia, getSignature
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from utils.pagination import PageOrNot
from apps.system.mixins import CreateUpdateModelAMixin
from rest_framework.decorators import action, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.status import HTTP_400_BAD_REQUEST
from django.utils import timezone
from rest_framework.exceptions import ParseError
from utils.queryset import get_child_queryset2
from django.db.models import Sum
from django.db import connection
# Create your views here.

class ClassView(APIView):

    perms_map={'get':'*'}
    def get(self, request, format=None):
        """
        查询分类
        """
        return getAllClass()

class VideoView(APIView):

    perms_map={'get':'video_view'}
    def get(self, request, format=None):
        """
        查询视频
        """
        params={'Filters':['basicInfo', 'metaData']}
        params['Offset'] = request.query_params.get('Offset', 0)
        params['Limit'] = request.query_params.get('Limit', 20)
        params['Names'] = request.query_params.getlist('name') if request.query_params.get('name') else []
        params['ClassIds']= request.query_params.getlist('classid') if request.query_params.get('classid') else []
        return searchMedia(params)

class VideoViewSet(PageOrNot, CreateUpdateModelAMixin, ModelViewSet):
    perms_map={'get':'video_view', 'post':'video_create', 'put':'video_update', 'delete':'video_delete'}
    queryset = Video.objects.all()
    search_fields = ['name', 'category__name', 'description']
    # filterset_fields = ['category']
    serializer_class = VideoSerializer
    ordering_fields = ['category__code', 'sort_str', 'views', 'viewsp']
    ordering = ['category__code', 'sort_str']

    def get_serializer_class(self):
        if self.action in ['list', 'retrieve']:
            return VideoListDetailSerializer
        elif self.action in ['update']:
            return VideoUpdateSerializer
        return super().get_serializer_class()

    def get_queryset(self):
        queryset = super().get_queryset()
        category = self.request.query_params.get('category', None)
        if category:
            categorys = get_child_queryset2(Dict.objects.get(pk=category))
            queryset = queryset.filter(category__in=categorys)
        return queryset
    
    @action(methods=['get'], detail=False, perms_map={'get':'video_view'})
    def myview(self, request, *args, **kwargs):
        """
        废弃接口

        个人观看记录
        """
        queryset = ViewRecord.objects.filter(user=request.user).order_by('-id')
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = VRecordSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = VRecordSerializer(queryset, many=True)
        return Response(serializer.data)
    
    @action(methods=['get'], detail=True, perms_map={'get':'*'})
    def my(self, request, *args, **kwargs):
        """
        本视频的我的观看统计

        本视频的我的观看统计
        """
        video = self.get_object()
        user = request.user
        ins, _ = View2.objects.get_or_create(create_by=user, video=video, defaults={'video': video, 'create_by': user})
        return Response(View2Serializer(instance=ins).data)
    
    @action(methods=['get'], detail=True, perms_map={'get':'*'})
    def start(self, request, *args, **kwargs):
        """
        开始播放

        本次播放开始返回记录ID,后续计时使用
        """
        video = self.get_object()
        user = request.user
        vi  = ViewItem.objects.create(create_by=user, video=video)
        cal_view1(vi)
        return Response({"vi": vi.id})

    # @action(methods=['get'], detail=False, perms_map={'get':'*'})
    # def correct_cate(self, request, *args, **kwargs):
    #     for video in Video.objects.get_queryset(all=True).all():
    #         cate = video.category
    #         video.category_big = cate
    #         if cate.pid:
    #             video.category_big = cate.pid
    #         video.save()
    #     return Response()

def cal_view1(vi: ViewItem):
    """
    统计视频播放数量

    统计视频播放数量
    """
    v1, _  = View1.objects.get_or_create(video=vi.video, defaults={"video": vi.video})
    v2, _ =  View2.objects.get_or_create(video=vi.video, create_by=vi.create_by, defaults={"video": vi.video, "create_by": vi.create_by})
    v1.views = ViewItem.objects.filter(video=vi.video).count()
    v1.viewp = View2.objects.filter(video=vi.video).count()
    v1.save()

def cal_view2(vi: ViewItem):
    """
    统计个人播放记录

    统计个人播放记录
    """
    v2, _ =  View2.objects.get_or_create(video=vi.video, create_by=vi.create_by, defaults={"video": vi.video, "create_by": vi.create_by})
    v2.views = ViewItem.objects.filter(video=vi.video).count()
    v2.total_seconds = ViewItem.objects.filter(video=vi.video).aggregate(total=Sum('total_seconds'))['total']
    v2.save()


class VRecordViewSet(ListModelMixin, GenericViewSet):
    """
    废弃接口

    废弃接口
    """
    perms_map = {'get':'viewrecord_view'}
    queryset = ViewRecord.objects.all()
    search_fields = ['user__name', 'video__name']
    serializer_class = VRecordSerializer
    ordering = ['-update_time']
    

class ViewItemViewSet(ListModelMixin, UpdateModelMixin, GenericViewSet):
    perms_map = {'get': 'viewitem_view', 'put': '*'}
    queryset = ViewItem.objects.select_related('create_by', 'video').all()
    search_fields = ['create_by__name', 'video__name']
    serializer_class = ViewItemSerializer
    ordering = ['-id']

    def get_serializer_class(self):
        if self.action == "update":
            return ViewItemUpdateSerializer
        return super().get_serializer_class()

    @action(methods=['get'], detail=False, perms_map={'get':'*'})
    def my(self, request, *args, **kwargs):
        """
        我的观看记录

        我的观看记录
        """
        queryset = ViewItem.objects.filter(create_by=request.user).order_by('-id')
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = ViewItemSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = ViewItemSerializer(queryset, many=True)
        return Response(serializer.data)

    def update(self, request, *args, **kwargs):
        user = request.user
        data = request.data
        obj = self.get_object()
        if obj.create_by != user:
            raise ParseError('非创建人')
        if ViewItem.objects.filter(video=obj.video, create_by=user).order_by('-id').first() != obj:
            raise ParseError('存在新播放记录')
        obj.current = data['current']
        obj.total_seconds = obj.total_seconds + data['seconds']
        obj.save()
        cal_view2(obj)
        return Response({'id': obj.id, 'current': obj.current, 'total_seconds': obj.total_seconds})
    
    @action(methods=['get'], detail=True, perms_map={'get':'*'})
    def complete(self, request, *args, **kwargs):
        """
        完成播放

        完成播放
        """
        obj = self.get_object()
        obj.current = 0
        v2 = View2.objects.get(video=obj.video, create_by=obj.create_by)
        if v2.total_seconds >= obj.video.duration * 0.6:
            v2.is_completed = True
            v2.save()
            return Response()
        raise ParseError('观看时长不足')

class View2ViewSet(ListModelMixin, GenericViewSet):
    perms_map = {'get': 'view2_view', 'put': '*'}
    queryset = View2.objects.select_related('create_by', 'video').all()
    search_fields = ['create_by__name', 'video__name']
    serializer_class = View2Serializer
    ordering = ['-id']

    @action(methods=['get'], detail=False, perms_map={'get':'*'})
    def my(self, request, *args, **kwargs):
        """
        我的观看统计

        我的观看统计
        """
        queryset = View2.objects.filter(create_by=request.user).order_by('-id')
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = View2Serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = View2Serializer(queryset, many=True)
        return Response(serializer.data)


class MyViewRecordAPIView(APIView):

    permission_classes = [IsAuthenticated]
    def get(self, request, id , format=None):
        """
        废弃接口

        该视频的本人观看信息
        """
        try:
            video = Video.objects.get(pk=id)
        except:
            return Response('视频不存在', status=HTTP_400_BAD_REQUEST)
        record = ViewRecord.objects.filter(video=video, user=request.user).first()
        if record:
            pass
        else:
            record = ViewRecord.objects.create(video=video, user=request.user)
        serializer = VRecordSerializer(instance=record)
        return Response(serializer.data)

    def put(self, request, id, format=None):
        """
        废弃接口

        更新该视频本人的观看信息
        params: {current:int}
        """
        try:
            video = Video.objects.get(pk=id)
        except:
            return Response('视频不存在', status=HTTP_400_BAD_REQUEST)
        
        record = ViewRecord.objects.filter(video=video, user=request.user).first()
        fcreated = True
        if record:
            fcreated = False
        else:
            record = ViewRecord.objects.create(video=video, user=request.user)

        if fcreated:
            video.viewsp = video.viewsp + 1
            video.views = video.views + 1
            record.views = 1
            video.save()
        if request.data.get('current', None):
            record.current = request.data.get('current')
        if timezone.now() > record.update_time + timedelta(minutes=30):
            record.views = record.views + 1
            video.views = video.views + 1
            video.save()
        else:
            record.total_seconds = record.total_seconds + 10
            record.save()
        record.save()
        return Response()

class SignatureAPIView(APIView):
    perms_map={'get':'video_create'}
    def get(self, request, format=None):
        """
        获取上传签名
        """
        return Response(getSignature(procedure=request.query_params.get('procedure', None)))


class PlayCodeAPIView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request, fileId):
        """获取播放签名
        """
        from .vodclient import appId
        try:
            playcode = getPlayCode(fileId)
        except:
            raise ParseError('获取签名失败')
        return Response({'psign':playcode, 'appId': appId})
