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

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

from Model.models import Lang, AiStoreMeal, AiService, Order_Model, Device_User, CountryModel, UidSetModel, Device_Info
from Object.ResponseObject import ResponseObject
from Object.TokenObject import TokenObject
from Service.CommonService import CommonService


class AiServeView(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):
        language = request_dict.get('language', 'en')
        response = ResponseObject(language, 'pc')
        if operation == 'xxx':  # 不认证token接口
            pass
        else:
            tko = TokenObject(
                request.META.get('HTTP_AUTHORIZATION'),
                returntpye='pc')
            if tko.code != 0:
                return response.json(tko.code)
            response.lang = tko.lang
            userID = tko.userID
            # ai套餐信息相关
            if operation == 'getAiStoreMealList':
                return self.getAiStoreMealList(request_dict, response)
            elif operation == 'addOrEditAiStoreMeal':
                return self.addOrEditAiStoreMeal(request_dict, response)
            elif operation == 'deleteAiStoreMeal':
                return self.deleteAiStoreMeal(request_dict, response)
            # ai套餐语言相关
            elif operation == 'getAiMealLanguage':
                return self.getAiMealLanguage(request_dict, response)
            elif operation == 'addOrEditAiMealLanguage':
                return self.addOrEditAiMealLanguage(request_dict, response)
            elif operation == 'deleteAiMealLanguage':
                return self.deleteAiMealLanguage(request_dict, response)
            # 设备ai套餐相关
            elif operation == 'getDeviceAiMealList':
                return self.getDeviceAiMealList(request_dict, response)
            # ai用户信息相关
            elif operation == 'getAiUserList':
                return self.getAiUserList(request_dict, response)
            # ai服务开通数量数据
            elif operation == 'getAiDataList':
                return self.getAiDataList(request_dict, response)
            else:
                return response.json(404)

    def getAiStoreMealList(self, request_dict, response):
        # 获取ai套餐信息数据
        print('request_dict: ', request_dict)

        isSelect = request_dict.get('isSelect', None)
        if isSelect:
            # 获取套餐ID作为选项
            ai_meal_qs = AiStoreMeal.objects.filter().values('id')
            return response.json(
                0, {'list': CommonService.qs_to_list(ai_meal_qs)})

        pageNo = request_dict.get('pageNo', None)
        pageSize = request_dict.get('pageSize', None)

        if not all([pageNo, pageSize]):
            return response.json(444)

        page = int(pageNo)
        line = int(pageSize)
        try:
            ai_meal_qs = AiStoreMeal.objects.filter()
            ai_meal_val = ai_meal_qs.values(
                'id',
                'price',
                'virtual_price',
                'symbol',
                'currency',
                'currency',
                'is_show',
                'is_discounts',
                'discount_price',
                'effective_day',
                'add_time',
                'update_time')
            total = len(ai_meal_val)
            ai_meals = ai_meal_val[(page - 1) * line:page * line]
            ai_meal_list = []
            for ai_meal in ai_meals:
                # 获取支付方式列表
                pay_type_list = [
                    pay_type['id'] for pay_type in AiStoreMeal.objects.get(
                        id=ai_meal['id']).pay_type.values('id')]
                # 组织响应数据
                ai_meal_list.append({
                    'aiMealID': ai_meal['id'],
                    'price': ai_meal['price'],
                    'virtual_price': ai_meal['virtual_price'],
                    'symbol': ai_meal['symbol'],
                    'currency': ai_meal['currency'],
                    'is_show': ai_meal['is_show'],
                    'is_discounts': ai_meal['is_discounts'],
                    'discount_price': ai_meal['discount_price'],
                    'effective_day': ai_meal['effective_day'],
                    'pay_type': pay_type_list,
                    'addTime': ai_meal['add_time'].strftime("%Y-%m-%d %H:%M:%S"),
                    'updTime': ai_meal['update_time'].strftime("%Y-%m-%d %H:%M:%S"),
                })
            print('store_meal_list: ', ai_meal_list)
            return response.json(
                0, {'list': ai_meal_list, 'total': total})
        except Exception as e:
            print(e)
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    def addOrEditAiStoreMeal(self, request_dict, response):
        # 添加/编辑套餐
        print('request_dict: ', request_dict)
        aiMealID = request_dict.get('aiMealID', None)
        effective_day = int(request_dict.get('effective_day', 0))
        price = request_dict.get('price', '')
        virtual_price = request_dict.get('virtual_price', '')
        currency = request_dict.get('currency', '')
        symbol = request_dict.get('symbol', '')
        pay_type = request_dict.get(
            'pay_type', '')[
                   1:-1].split(',')  # '[1,2]' -> ['1','2']
        is_discounts = int(request_dict.get('is_discounts', 0))
        discount_price = request_dict.get('discount_price', '')
        is_show = int(request_dict.get('is_show', 1))
        isEdit = request_dict.get('isEdit', None)

        if not all([effective_day, price, currency, symbol, pay_type]):
            return response.json(444)

        try:
            ai_store_meal_data = {
                'effective_day': effective_day,
                'price': price,
                'virtual_price': virtual_price,
                'currency': currency,
                'symbol': symbol,
                'is_discounts': is_discounts,
                'discount_price': discount_price,
                'is_show': is_show,
            }
            if isEdit:
                if not aiMealID:
                    return response.json(444)
                AiStoreMeal.objects.filter(
                    id=aiMealID).update(
                    **ai_store_meal_data)
                AiStoreMeal.objects.get(id=aiMealID).pay_type.set(pay_type)
            else:
                AiStoreMeal.objects.create(
                    **ai_store_meal_data).pay_type.set(pay_type)
            return response.json(0)
        except Exception as e:
            print(e)
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    def deleteAiStoreMeal(self, request_dict, response):
        # 删除ai套餐
        print('request_dict: ', request_dict)
        aiMealID = request_dict.get('aiMealID', None)
        if not aiMealID:
            return response.json(444)
        try:
            AiStoreMeal.objects.filter(id=aiMealID).delete()
            return response.json(0)
        except Exception as e:
            print(e)
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    def getAiMealLanguage(self, request_dict, response):
        # 获取ai套餐语言
        print('request_dict: ', request_dict)
        aiMealID = request_dict.get('aiMealID', None)
        pageNo = request_dict.get('pageNo', None)
        pageSize = request_dict.get('pageSize', None)

        if not all([pageNo, pageSize]):
            return response.json(444)

        page = int(pageNo)
        line = int(pageSize)
        try:
            if aiMealID:  # 条件查询
                store_meal_lang_qs = AiStoreMeal.objects.filter(id=aiMealID)
            else:  # 查询全部
                store_meal_lang_qs = AiStoreMeal.objects.filter(
                    lang__isnull=False)
            ai_meal_lang_val = store_meal_lang_qs.values(
                'id',
                'lang__id',
                'lang__lang',
                'lang__title',
                'lang__content',
                'lang__discount_content',
            )
            total = len(ai_meal_lang_val)
            ai_meal_langs = ai_meal_lang_val[(
                                                     page - 1) * line:page * line]
            ai_meal_lang_list = []
            for ai_meal_lang in ai_meal_langs:
                ai_meal_lang_list.append({
                    'aiMealID': ai_meal_lang['id'],
                    'langID': ai_meal_lang['lang__id'],
                    'lang': ai_meal_lang['lang__lang'],
                    'title': ai_meal_lang['lang__title'],
                    'content': ai_meal_lang['lang__content'],
                    'discountContent': ai_meal_lang['lang__discount_content'],
                })
            print('ai_meal_lang_list: ', ai_meal_lang_list)
            return response.json(
                0, {'list': ai_meal_lang_list, 'total': total})
        except Exception as e:
            print(e)
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    def addOrEditAiMealLanguage(self, request_dict, response):
        # 添加/编辑套餐语言
        print('request_dict: ', request_dict)
        aiMealID = request_dict.get('aiMealID', None)
        lang = request_dict.get('lang', None)
        title = request_dict.get('title', None)
        content = request_dict.get('content', '')
        discount_content = request_dict.get('discountContent', '')
        isEdit = request_dict.get('isEdit', None)

        if not all([aiMealID, lang, title]):
            return response.json(444)

        try:
            # 查询套餐是否存在
            ai_meal_qs = AiStoreMeal.objects.get(id=aiMealID)
            if not ai_meal_qs:
                return response.json(173)
            if isEdit:  # 编辑
                langID = request_dict.get('langID', None)
                if not langID:
                    return response.json(444)
                Lang.objects.filter(
                    id=langID).update(
                    lang=lang,
                    title=title,
                    content=content,
                    discount_content=discount_content)
            else:  # 添加
                lang_obj = Lang.objects.filter(
                    lang=lang,
                    title=title,
                    content=content,
                    discount_content=discount_content)
                if not lang_obj.exists():
                    # 数据不存在,lang表创建数据
                    Lang.objects.create(
                        lang=lang,
                        title=title,
                        content=content,
                        discount_content=discount_content,
                        type=1)
                    lang_obj = Lang.objects.filter(
                        lang=lang,
                        title=title,
                        content=content,
                        discount_content=discount_content)
                ai_meal_qs.lang.add(*lang_obj)  # store_meal表添加语言数据
            return response.json(0)
        except Exception as e:
            print(e)
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    def deleteAiMealLanguage(self, request_dict, response):
        # 删除套餐语言
        aiMealID = request_dict.get('aiMealID', None)
        langID = request_dict.get('langID', None)

        if not all([aiMealID, langID]):
            return response.json(444)

        try:
            ai_meal_qs = AiStoreMeal.objects.get(id=aiMealID)
            if not ai_meal_qs:
                return response.json(173)
            lang_qs = Lang.objects.filter(id=langID)
            ai_meal_qs.lang.remove(*lang_qs)
            return response.json(0)
        except Exception as e:
            print(e)
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    def getDeviceAiMealList(self, request_dict, response):
        pageNo = request_dict.get('pageNo', None)
        pageSize = request_dict.get('pageSize', None)
        uid = request_dict.get('uid', None)
        serialNumber = request_dict.get('serialNumber', None)
        if not all([pageNo, pageSize]):
            return response.json(444)

        page = int(pageNo)
        line = int(pageSize)
        try:
            ai_service_qs = AiService.objects.all()
            if uid:
                ai_service_qs = ai_service_qs.filter(uid__contains=uid)
            if serialNumber:
                device_info_qs = Device_Info.objects.filter(serial_number=serialNumber).values('UID')
                uid = device_info_qs[0]['UID'] if device_info_qs.exists() else 'N/A'
                ai_service_qs = ai_service_qs.filter(uid__icontains=uid)

            if not ai_service_qs.exists():
                return response.json(0, [])

            count = ai_service_qs.count()
            ai_service_qs = ai_service_qs.annotate(
                user_name=F('orders__userID__username')).values(
                'id',
                'uid',
                'channel',
                'use_status',
                'detect_status',
                'detect_group',
                'endTime',
                'addTime',
                'updTime', 'user_name').order_by('-addTime')
            ai_service_qs = ai_service_qs[(page - 1) * line:page * line]
            ai_service_list = []
            for ai_service in ai_service_qs:
                data = {
                    'id': ai_service['id'],
                    'uid': ai_service['uid'],
                    'channel': ai_service['channel'],
                    'use_status': ai_service['use_status'],
                    'detect_status': ai_service['detect_status'],
                    'detect_group': ai_service['detect_group'],
                    'endTime': ai_service['endTime'],
                    'addTime': ai_service['addTime'],
                    'updTime': ai_service['updTime'],
                    'user_name': ai_service['user_name'],
                    'serial_number': 'N/A'
                }
                device_info_qs = Device_Info.objects.filter(UID=ai_service['uid']).values('serial_number')
                if device_info_qs.exists():
                    data['serial_number'] = device_info_qs[0]['serial_number'] if device_info_qs[0]['serial_number'] else 'N/A'
                ai_service_list.append(data)
            return response.json(
                0, {'list': ai_service_list, 'total': count})
        except Exception as e:
            print(e)
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    def getAiUserList(self, request_dict, response):
        username = request_dict.get('username', None)
        NickName = request_dict.get('NickName', None)
        uid = request_dict.get('uid', None)
        payType = request_dict.get('payType', None)
        status = request_dict.get('status', None)
        use_status = request_dict.get('use_status', None)
        serialNumber = request_dict.get('serialNumber', None)
        addTimeRange = request_dict.getlist('addTimeRange[]', None)

        pageNo = request_dict.get('pageNo', None)
        pageSize = request_dict.get('pageSize', None)
        if not all([pageNo, pageSize]):
            return response.json(444)
        page = int(pageNo)
        line = int(pageSize)

        try:
            order_qs = Order_Model.objects.filter(
                order_type=1).order_by('-addTime')
            if username or NickName or uid or payType or status or use_status or addTimeRange or serialNumber:
                if username:
                    order_qs = order_qs.filter(
                        userID__username__contains=username)
                if NickName:
                    order_qs = order_qs.filter(
                        userID__NickName__contains=NickName)
                if uid:
                    order_qs = order_qs.filter(UID__contains=uid)
                if payType:
                    order_qs = order_qs.filter(payType=payType)
                if status:
                    order_qs = order_qs.filter(status=status)
                if use_status:
                    order_qs = order_qs.filter(use_status=use_status)
                if serialNumber:
                    device_info_qs = Device_Info.objects.filter(serial_number=serialNumber).values('UID')
                    uid = device_info_qs[0]['UID'] if device_info_qs.exists() else 'N/A'
                    order_qs = order_qs.filter(UID=uid)
                if addTimeRange:
                    addStartTime, addEndTime = int(
                        addTimeRange[0][:-3]), int(addTimeRange[1][:-3])
                    order_qs = order_qs.filter(
                        addTime__gte=addStartTime,
                        addTime__lte=addEndTime)
                if not order_qs.exists():
                    return response.json(0, {'list': [], 'total': 0})
                count = order_qs.count()
            else:
                count = Order_Model.objects.filter(order_type=1).count()
            order_qs = order_qs.values(
                'userID__username',
                'userID__NickName',
                'UID',
                'channel',
                'orderID',
                'desc',
                'payType',
                'price',
                'status',
                'refunded_amount',
                'addTime',
                'updTime', 'userID_id',
            )[(page - 1) * line:page * line]
            data_list = []
            for order in order_qs:
                data_dict = {
                    'username': order['userID__username'],
                    'NickName': order['userID__NickName'],
                    'uid': order['UID'],
                    'channel': order['channel'],
                    'orderID': order['orderID'],
                    'desc': order['desc'],
                    'payType': order['payType'],
                    'price': order['price'],
                    'status': order['status'],
                    'refunded_amount': order['refunded_amount'],
                    'addTime': order['addTime'],
                    'updTime': order['updTime'],
                }
                us_qs = UidSetModel.objects.filter(uid=order['UID']).values('ip')
                data_dict['ip'] = us_qs.first()['ip'] if us_qs.exists() else ''
                dev_user_qs = Device_User.objects.filter(userID=order['userID_id']).values('region_country')
                region_country = dev_user_qs.first()['region_country']
                country = '未知国家'
                country_qs = CountryModel.objects.filter(id=region_country).values('country_name')
                if country_qs.exists():
                    country = country_qs.first()['country_name']
                data_dict['country'] = country
                data_dict['deviceCountry'] = self.get_device_country(data_dict['ip'])
                uid_set_qs = UidSetModel.objects.filter(uid=order['UID']).values('version')
                data_dict['version'] = uid_set_qs.first()['version'] if uid_set_qs.exists() else ''
                ai_service_qs = AiService.objects.filter(
                    orders_id=order['orderID']).values(
                    'endTime', 'use_status')
                if ai_service_qs.exists():
                    data_dict['endTime'] = ai_service_qs[0]['endTime']
                    data_dict['use_status'] = ai_service_qs[0]['use_status']
                data_dict['serial_number'] = 'N/A'
                device_info_qs = Device_Info.objects.filter(UID=order['UID']).values('serial_number')
                if device_info_qs.exists():
                    data_dict['serial_number'] = device_info_qs[0]['serial_number'] if device_info_qs[0][
                        'serial_number'] else 'N/A'
                data_list.append(data_dict)
            return response.json(
                0, {'list': data_list, 'total': count})
        except Exception as e:
            print(e)
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    @staticmethod
    def get_device_country(ip):
        """
        根据IP获取国家名称
        """
        if not ip:
            return '未知国家'
        ipInfo = CommonService.getIpIpInfo(ip, 'EN')
        country_qs = CountryModel.objects.filter(country_code=ipInfo['country_code']).values('id', 'country_name')
        if not country_qs.exists():
            return '未知国家'
        return country_qs[0]['country_name']

    def getAiDataList(self, request_dict, response):
        year = request_dict.get('year', None)
        Jan = int(time.mktime(time.strptime(year + '-1-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
        Feb = int(time.mktime(time.strptime(year + '-2-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
        Mar = int(time.mktime(time.strptime(year + '-3-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
        Apr = int(time.mktime(time.strptime(year + '-4-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
        May = int(time.mktime(time.strptime(year + '-5-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
        Jun = int(time.mktime(time.strptime(year + '-6-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
        Jul = int(time.mktime(time.strptime(year + '-7-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
        Aug = int(time.mktime(time.strptime(year + '-8-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
        Sep = int(time.mktime(time.strptime(year + '-9-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
        Oct = int(time.mktime(time.strptime(year + '-10-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
        Nov = int(time.mktime(time.strptime(year + '-11-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
        Dec = int(time.mktime(time.strptime(year + '-12-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
        Jan_next = int(time.mktime(time.strptime(str(int(year) + 1) + '-1-1 00:00:00', "%Y-%m-%d %H:%M:%S")))

        list_data = []
        ai_store_meal_qs = AiStoreMeal.objects.filter(lang__lang='cn').values('id', 'lang__title', 'lang__content')
        if not ai_store_meal_qs.exists():
            return response.json(173)
        try:
            for ai_store_meal in ai_store_meal_qs:
                name = ai_store_meal['lang__title'] + '-' + ai_store_meal['lang__content']
                order = Order_Model.objects.filter(order_type=1, status=1, ai_rank=ai_store_meal['id'])
                if not order.exists():
                    continue
                Jan_count = order.filter(status=1, addTime__range=[Jan, Feb]).count()
                Feb_count = order.filter(status=1, addTime__range=[Feb, Mar]).count()
                Mar_count = order.filter(status=1, addTime__range=[Mar, Apr]).count()
                Apr_count = order.filter(status=1, addTime__range=[Apr, May]).count()
                May_count = order.filter(status=1, addTime__range=[May, Jun]).count()
                Jun_count = order.filter(status=1, addTime__range=[Jun, Jul]).count()
                Jul_count = order.filter(status=1, addTime__range=[Jul, Aug]).count()
                Aug_count = order.filter(status=1, addTime__range=[Aug, Sep]).count()
                Sep_count = order.filter(status=1, addTime__range=[Sep, Oct]).count()
                Oct_count = order.filter(status=1, addTime__range=[Oct, Nov]).count()
                Nov_count = order.filter(status=1, addTime__range=[Nov, Dec]).count()
                Dec_count = order.filter(status=1, addTime__range=[Dec, Jan_next]).count()
                data = [Jan_count, Feb_count, Mar_count, Apr_count, May_count, Jun_count, Jul_count, Aug_count,
                        Sep_count,
                        Oct_count, Nov_count, Dec_count]

                cloud_data = {
                    'name': name,
                    'type': 'line',
                    'data': data,
                }
                list_data.append(cloud_data)

            return response.json(0, {'list': list_data})
        except Exception as e:
            print(e)
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
