import hashlib
import logging
import time
import uuid

from django.db.models import F
from django.http import StreamingHttpResponse
from django.views.generic.base import View

from Model.models import CDKcontextModel
from Object.ResponseObject import ResponseObject
from Object.TokenObject import TokenObject


class CDKView(View):

    def get(self, request, *args, **kwargs):
        request.encoding = 'utf-8'
        operation = kwargs.get('operation')
        return self.validation(request.GET, request, operation)

    def post(self, request, *args, **kwargs):
        request.encoding = 'utf-8'
        operation = kwargs.get('operation')
        return self.validation(request.POST, request, operation)

    def validation(self, request_dict, request, operation):
        response = ResponseObject()

        if operation is None:
            return response.json(444, 'error path')
        else:
            token = request_dict.get('token', None)
            tko = TokenObject(token)
            response.lang = tko.lang
            if tko.code != 0:
                return response.json(tko.code)
            userID = tko.userID
            if operation == 'createCDK':
                return self.createCDK(request_dict, response)
            elif operation == 'deleteCDK':
                return self.deleteCDK(request_dict, response)
            elif operation == 'queryCDK':
                return self.queryCDK(request_dict, response)
            elif operation == 'saveOrEditCDK':
                return self.saveOrEditCDK(request_dict, response)
            elif operation == 'downloadCDK':
                return self.downloadCDK(request_dict, response)

    def createCDK(self, request_dict, response):
        cdk_num = request_dict.get("cdknum", None)
        rank = request_dict.get('rank', None)
        order = request_dict.get('order', None)
        cdk_list = []
        for i in range(int(cdk_num)):
            nowTime = int(time.time())
            cdk = hashlib.md5((str(uuid.uuid1()) + str(nowTime)).encode('utf-8')).hexdigest()
            cdk_model = CDKcontextModel(
                cdk=cdk,
                create_time=nowTime,
                valid_time=0,
                is_activate=0,
                is_down=0,
                rank_id=rank,
                order=order,
            )
            cdk_list.append(cdk_model)
        try:
            CDKcontextModel.objects.bulk_create(cdk_list)
        except Exception as e:
            print(repr(e))
            return response.json(404, repr(e))
        else:
            return response.json(0)

    def queryCDK(self, request_dict, response):
        page = int(request_dict.get('page', None))
        line = int(request_dict.get('line', None))
        # channel = request_dict.get('channel', None)
        cdk = request_dict.get('cdk', None)
        order = request_dict.get('order', None)
        is_activate = request_dict.get('is_activate', None)
        lang = request_dict.get('lang', 'cn')
        searchVal = ''
        if cdk:
            searchVal = cdk.strip()
        elif order:
            searchVal = order.strip()
        elif is_activate:
            searchVal = is_activate.strip()
        logger = logging.getLogger('info')
        logger.info('CDK测试打印1: {}'.format(time.localtime(time.time())))
        if page and line:
            cdk_qs = CDKcontextModel.objects.filter().all()
            if searchVal:
                if cdk:
                    cdk_qs = cdk_qs.filter(cdk__contains=searchVal)
                elif order:
                    cdk_qs = cdk_qs.filter(order=searchVal)
                elif is_activate:
                    cdk_qs = cdk_qs.filter(is_activate=searchVal)

            cdk_qs = cdk_qs.filter(rank__lang__lang=lang)
            cdk_qs = cdk_qs.annotate(rank__title=F('rank__lang__title'))
            cdk_qs = cdk_qs.values('id', 'cdk', 'create_time', 'valid_time', 'is_activate', 'rank__id', 'rank__title',
                                   'rank__bucket__mold', 'order', 'create_time')
            cdk_qs = cdk_qs.order_by('-create_time')  # 根据CDK创建时间降序排序
            count = cdk_qs.count()
            cdk_qs = cdk_qs[(page - 1) * line:page * line]

            res = {
                'datas': list(cdk_qs),
                'count': count
            }
            logger.info('CDK测试打印2: {}'.format(time.localtime(time.time())))
            return response.json(0, res)
        else:
            return response.json(444, 'page,line')

    def deleteCDK(self, request_dict, response):
        cdk_id = request_dict.get("id", None)
        lang = request_dict.get("lang", 'cn')
        try:
            CDKcontextModel.objects.get(cdk=cdk_id).delete()
        except Exception as e:
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
        else:
            page = int(request_dict.get('page', None))
            line = int(request_dict.get('line', None))
            # channel = request_dict.get('channel', None)
            cdk = request_dict.get('cdk', None)
            order = request_dict.get('order', None)
            is_activate = request_dict.get('is_activate', None)

            searchVal = ''
            if cdk:
                searchVal = cdk.strip()
            elif order:
                searchVal = order.strip()
            elif is_activate:
                searchVal = is_activate.strip()

            if page and line:
                cdk_qs = CDKcontextModel.objects.filter().all()
                if searchVal:
                    if cdk:
                        cdk_qs = cdk_qs.filter(cdk__contains=searchVal)
                    elif order:
                        cdk_qs = cdk_qs.filter(order=searchVal)
                    elif is_activate:
                        cdk_qs = cdk_qs.filter(is_activate=searchVal)

                cdk_qs = cdk_qs.filter(rank__lang__lang=lang)
                cdk_qs = cdk_qs.annotate(rank__title=F('rank__lang__title'))
                cdk_qs = cdk_qs.values('id', 'cdk', 'create_time', 'valid_time', 'is_activate', 'rank__id',
                                       'rank__title', 'order',
                                       'create_time')
                cdk_qs = cdk_qs.order_by('-create_time')  # 根据CDK创建时间降序排序
                count = cdk_qs.count()
                cdk_qs = cdk_qs[(page - 1) * line:page * line]
                res = {
                    'datas': list(cdk_qs),
                    'count': count
                }
                return response.json(0, res)

    def saveOrEditCDK(self, request_dict, response):
        cdk_id = request_dict.get("id", None)
        cdk = request_dict.get('cdk', None)
        valid_time = request_dict.get('valid_time', None)
        is_activate = request_dict.get('is_activate', None)
        rank = request_dict.get('rank', None)

        try:
            if cdk_id:
                if cdk or valid_time or is_activate or rank:
                    update_dict = {}
                    if cdk:
                        update_dict['cdk'] = cdk
                    if valid_time:
                        update_dict['valid_time'] = valid_time
                    if is_activate:
                        update_dict['is_activate'] = is_activate
                    if rank:
                        update_dict['rank'] = rank
                    CDKcontextModel.objects.filter(id=cdk_id).update(**update_dict)
        except Exception as e:
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
        else:
            return response.json(0)

    def downloadCDK(self, request_dict, response):
        region = request_dict.get('region', None)
        content = ''
        if region == 'cn':
            # 下载国内未使用激活码
            content += '激活码(国内)\n'
            cdk_inactivate_qs = CDKcontextModel.objects.filter(is_down=0, is_activate=0, rank__bucket__mold=0,
                                                               rank__is_show=0).values('cdk')
        else:
            # 下载国外未使用激活码
            content += '激活码(国外)\n'
            cdk_inactivate_qs = CDKcontextModel.objects.filter(is_down=0, is_activate=0, rank__bucket__mold=1,
                                                               rank__is_show=0).values('cdk')
        for cdk_inactivate in cdk_inactivate_qs:
            content += cdk_inactivate['cdk'] + '\n'

        cdk_inactivate_qs.update(is_down=1)
        response = StreamingHttpResponse(content)
        response['Content-Type'] = 'application/octet-stream'
        response['Content-Disposition'] = 'attachment;filename="CDK.txt"'
        return response
