#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import logging
import random
import time

from bulk_update.helper import bulk_update
from django.db import transaction
from django.db.models import Count
from django.views import View

from Model.models import SerialNumberModel, UserModel, UserSerialNumberModel, UserUIDModel, CompanySerialModel
from Object.RedisObject import RedisObject
from Object.ResponseObject import ResponseObject
from Object.TokenObject import TokenObject
from Service.AlgorithmService import AlgorithmBaseOn35
from Service.CommonService import CommonService
from Service.ModelService import ModelService


class SerialNumberView(View):

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

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

    def validate(self, request_dict, operation):
        response = ResponseObject()
        if operation == 'create':
            return self.do_create(request_dict, response)

        token = request_dict.get('token', None)
        token = TokenObject(token)
        if token.code != 0:
            return response.json(token.code)

        if operation == 'quantity':
            return self.do_quantity(request_dict,token.userID, response)
        elif operation == 'allot':
            return self.do_allot(request_dict, response)
        else:
            return response.json(309)

    # 查询当前可用的UID的数量
    def do_quantity(self, request_dict, userID, response):
        user_qs = UserModel.objects.filter(id=userID)
        if not user_qs.exists():
            return response.json(9)

        user = user_qs[0]
        chenyunsuper = SerialNumberModel.objects.filter(p2p=1).count()
        tutksuper = SerialNumberModel.objects.filter(p2p=2).count()

        result = UserSerialNumberModel.objects.filter(user__id=user.id, serial_number__p2p=1, serial_number__use_status=1).aggregate(num=Count('serial_number__use_status'))
        chenyundev = result['num']
        result2 = UserSerialNumberModel.objects.filter(user__id=user.id, serial_number__p2p=2, serial_number__use_status=1).aggregate(num=Count('serial_number__use_status'))
        tutkdev = result2['num']

        chenyun = SerialNumberModel.objects.filter(use_status=1, p2p=1).count()
        tutk = SerialNumberModel.objects.filter(use_status=1, p2p=2).count()
        res_data = {'code': 0, 'chenyun': chenyun, 'tutk': tutk, 'chenyunsuper': chenyunsuper, 'tutksuper': tutksuper, 'chenyundev': chenyundev, 'tutkdev': tutkdev}
        return response.json(0, {'data': res_data})

    def do_create(self, request_dict, response):
        quantity = int(request_dict.get('quantity', 0))
        p2p = int(request_dict.get('p2p', 0))

        if not quantity:
            return response.json(444)

        try:
            try:
                sum = SerialNumberModel.objects.last().id
            except:
                sum = 0
            serial_number_bulk = []
            now_time = int(time.time())
            algorithm = AlgorithmBaseOn35()
            for i in range(quantity):
                serial_number = algorithm.getLetter(sum)
                sum += 1    # sum每次递增1
                # 前面补0至六位
                serial_number = (6-len(serial_number))*'0' + serial_number
                serial_number_bulk.append(SerialNumberModel(serial_number=serial_number, add_time=now_time, p2p=p2p))
            # 开启事务写入
            with transaction.atomic():
                SerialNumberModel.objects.bulk_create(serial_number_bulk)
            return response.json(0)
        except Exception as e:
            print(e)
            return response.json(500, repr(e))

    # 分配序列号
    @transaction.atomic
    def do_allot(self, request_dict, response):
        username = request_dict.get('username', None)
        quantity = int(request_dict.get('quantity', None))
        area = request_dict.get('area', None)
        token = request_dict.get('token', None)

        token = TokenObject(token)
        if token.code != 0:
            return response.json(token.code)
        user = UserModel.objects.get(id=token.userID)

        if not user or '0' not in user.permission:
            return response.json(404)

        # 要分配的对象
        allot_user_qs = UserModel.objects.filter(username=username)
        if not allot_user_qs.exists():
            return response.json(444, 'username')

        # 取出对应区域可用的UID分配给allot_user
        sn_qs = SerialNumberModel.objects.filter(p2p=area, use_status=0)[0:quantity]
        sns = []
        for sn in sn_qs:
            sns.append(sn.serial_number)

        cs_qs = CompanySerialModel.objects.filter(serial_number__in=sns, status=1)

        sns = []
        for cs in cs_qs:
            sns.append(cs.serial_number)
        sn_qs = SerialNumberModel.objects.filter(serial_number__in=sns)

        count = sn_qs.count()
        if count < quantity:
            return response.json(444, '序列号不足')

        updates = []
        datas = []
        count = 0
        if sn_qs.exists():
            sn_qs = sn_qs[0:quantity]
            now_time = int(time.time())
            for i in range(len(sn_qs)):
                item = sn_qs[i]
                serialNumberModel = SerialNumberModel(
                    id=item.id,
                    serial_number=item.serial_number,
                    status=item.status,
                    use_status=1,
                    p2p=item.p2p,
                    add_time=item.add_time
                )
                user_serial_number = UserSerialNumberModel()
                user_serial_number.serial_number = serialNumberModel
                user_serial_number.user = allot_user_qs[0]
                user_serial_number.add_time = now_time
                user_serial_number.update_time = now_time

                datas.append(user_serial_number)
                updates.append(serialNumberModel)

                if len(updates) % 5000 == 0:
                    bulk_update(updates)
                    UserSerialNumberModel.objects.bulk_create(datas)

            if len(updates) > 0:
                bulk_update(updates)
                UserSerialNumberModel.objects.bulk_create(datas)

            del datas
            del updates
            return response.json(0)
        else:
            return response.json(444)
