#!/usr/bin/env python3  
# -*- coding: utf-8 -*-  
"""
@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
@AUTHOR: ASJRD018
@NAME: AnsjerFormal
@software: PyCharm
@DATE: 2018/12/6 10:53
@Version: python3.6
@MODIFY DECORD:ansjer dev
@file: OrderContrller.py
@Contact: chanjunkai@163.com
"""
import time

import paypalrestsdk
from django.db.models import F
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.views.generic.base import View

from Ansjer.config_test import PAYPAL_CRD
from Object.AliPayObject import AliPayObject
from Object.ResponseObject import ResponseObject
from Object.TokenObject import TokenObject
from Model.models import Order_Model, Device_Info
from Service.CommonService import CommonService
from Service.ModelService import ModelService

'''
# 获取所有设备下单信息
http://192.168.136.40:8077/order/querylist?token=local&page=1&line=10
'''


# 设备信息添加
class OrderView(View):
    @method_decorator(csrf_exempt)
    def dispatch(self, *args, **kwargs):
        return super(OrderView, self).dispatch(*args, **kwargs)

    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')
        token = request_dict.get('token', None)
        # 设备主键uid
        tko = TokenObject(token)
        response.lang = request_dict.get('language', 'en')
        if tko.code != 0:
            return response.json(tko.code)
        userID = tko.userID
        if operation == 'querylist':
            return self.do_querylist(request_dict, userID, response)
        elif operation == 'adminDelete':
            return self.do_admin_delete(request_dict, userID, response)
        elif operation == 'adminQuery':
            return self.do_admin_query(request_dict, userID, response)
        elif operation == 'detail':
            return self.do_detail(request_dict, userID, response)
        elif operation == 'queryByStatus':
            return self.do_query_order_by_status(request_dict, userID, response)
        elif operation == 'orderDetail':
            return self.do_query_order_detail(request_dict, userID, response)
        elif operation == 'cancel':
            return self.do_cancel_order(request_dict, userID, response)
        elif operation == 'delete':
            return self.do_delete_order(request_dict, userID, response)
        else:
            return response.json(444, 'error path')

    def do_detail(self, request_dict, userID, response):
        orderID = request_dict.get('orderID', None)
        om_qs = Order_Model.objects.filter(userID_id=userID, orderID=orderID).values('status')
        if om_qs.exists():
            return response.json(0, {'status': om_qs[0]['status']})
        else:
            return response.json(173)

    def do_querylist(self, request_dict, userID, response):
        page = request_dict.get('page', None)
        line = request_dict.get('line', None)
        uid = request_dict.get('uid', None)
        lang = request_dict.get('lang', 'en')
        if not page or not line:
            return response.json(444, 'page,line')
        page = int(page)
        line = int(line)
        omqs = Order_Model.objects.filter(userID_id=userID, status=1, rank__lang__lang=lang)
        # 筛选指定设备id的订单
        if uid:
            omqs.filter(UID=uid)
        if not omqs.exists():
            return response.json(173)
            # return response.json(10, '订单不存在')
        count = omqs.count()
        omqs = omqs.annotate(rank__title=F('rank__lang__title'), rank__content=F('rank__lang__content'))
        order_ql = omqs[(page - 1) * line:page * line].values("orderID", "UID", "channel", "desc", "price", "currency",
                                                              "addTime",
                                                              "updTime", "paypal", "rank__day", "payType",
                                                              "rank__price", "status",
                                                              "rank__content", "rank__title", "rank__currency",
                                                              "rank_id","rank__expire")
        order_list = list(order_ql)
        data = []
        nowTime = int(time.time())
        # 这里需要进行优化
        uid_list = []
        for od in order_list:
            uid_list.append(od['UID'])
        didqs = Device_Info.objects.filter(userID_id=userID, UID__in=uid_list).values('id', 'UID', 'Type')
        for d in order_list:
            if d['status'] == 0:
                if d['addTime'] + 3600 < nowTime:
                    d['status'] = 3
            for did in didqs:
                if d['UID'] == did['UID']:
                    d['did'] = did['id']
                    d['Type'] = did['Type']
                    data.append(d)
            d['rank__expire_unit'] = '月' if lang == 'cn' else 'month'
        return response.json(0, {'data': data, 'count': count})

    # admins ^^^^^^^^^^^^
    def do_admin_delete(self, request_dict, userID, response):
        own_perm = ModelService.check_perm(userID, 20)
        if own_perm is True:
            orderID = request_dict.get('orderID')
            Order_Model.objects.filter(orderID=orderID).delete()
            return response.json(0)
        else:
            return response.json(404)

    def do_admin_query(self, request_dict, userID, response):
        own_perm = ModelService.check_perm(userID, 20)
        if own_perm is True:
            page = request_dict.get('page', None)
            line = request_dict.get('line', None)
            uid = request_dict.get('uid', None)
            channel = request_dict.get('channel', None)
            orderID = request_dict.get('orderID', None)
            page = int(page)
            line = int(line)
            omqs = Order_Model.objects.all()
            # 筛选指定设备id的订单
            if uid:
                omqs = omqs.filter(UID=uid)
            if channel:
                omqs = omqs.filter(channel=channel)
            if orderID:
                omqs = omqs.filter(orderID=orderID)
            if not omqs.exists():
                return response.json(0, [])
            count = omqs.count()
            order_ql = omqs[(page - 1) * line:page * line].values("orderID", "UID", "channel", "desc", "price",
                                                                  "currency", "addTime", "updTime", "paypal",
                                                                  "payType",
                                                                  "rank__day",
                                                                  "rank__price", "status")
            order_list = list(order_ql)
            return response.json(0, {'data': order_list, 'count': count})

        else:
            return response.json(404)

    def do_query_order_by_status(self, request_dict, userID, response):
        status = request_dict.get('status', None)
        page = request_dict.get('page', None)
        line = request_dict.get('line', None)
        lang = request_dict.get('lang', 'en')
        if status and page and line:
            order_qs = None
            status = int(status)
            if status == -1: # 获取所有订单
                order_qs = Order_Model.objects.filter(userID__userID=userID,rank__lang__lang=lang)
            elif status == 0: # 获取【代付款】订单
                order_qs = Order_Model.objects.filter(userID__userID=userID, status=0,rank__lang__lang=lang)
            elif status == 1:
                order_qs = Order_Model.objects.filter(userID__userID=userID, status=1,rank__lang__lang=lang)

            if order_qs is None or not order_qs.exists():
                return response.json(0, {'data': [], 'count': 0})

            page = int(page)
            line = int(line)
            start = (page - 1) * line
            end = status + line
            count = order_qs.count()
            order_qs = order_qs.annotate(rank__title=F('rank__lang__title'))
            order_qs = order_qs[start:end].values("orderID", "UID", "channel", "desc", "price",
                                                  "currency", "addTime", "payType", "rank__day", "rank__price",
                                                  "status", 'channel', "rank__title", "currency")
            return response.json(0, {'data': list(order_qs), 'count': count})
        else:
            return response.json(444)

    def do_query_order_detail(self, request_dict, userID, response):
        orderID = request_dict.get('orderID', None)
        lang = request_dict.get('lang', 'en')
        if orderID:
            order_qs = Order_Model.objects.filter(orderID=orderID, userID__userID=userID, rank__lang__lang=lang)
            if order_qs.exists():
                print(order_qs)
                order_qs = order_qs.annotate(rank__title=F('rank__lang__title'))
                order = order_qs.values("orderID", "UID", "channel", "desc", "price",
                                        "currency", "addTime", "endTime", "payType",
                                        "rank__day", "rank__price", "status", 'channel', "rank__title", "currency")[0]

                return response.json(0, {'data': order})
            else:
                return response.json(173)
        else:
            return response.json(444)

    def do_cancel_order(self, request_dict, userID, response):
        orderID = request_dict.get('orderID', None)
        lang = request_dict.get('lang', 'en')
        if orderID is None:
            return response.json(444)

        order_qs = Order_Model.objects.filter(orderID=orderID,rank__lang__lang=lang)
        if not order_qs.exists():
            return response.json(800)

        order = order_qs[0]
        if order.status != 0:
            return response.json(802)

        if order.payType == 1: # 支付宝支付的订单
            return self.do_cancel_alipay_order(order, response)
        else:
            return self.do_cancel_paypal_order(order, response)

    def do_delete_order(self, request_dict, userID, response):
        orderID = request_dict.get('orderID', None)

        if orderID:
            Order_Model.objects.filter(orderID=orderID, userID__userID=userID).delete()
            return response.json(0)
        else:
            return response.json(444)

    def do_cancel_alipay_order(self, order, response):
        # 交易状态：
        # WAIT_BUYER_PAY（交易创建，等待买家付款）
        # TRADE_CLOSED（未付款交易超时关闭，或支付完成后全额退款）
        # TRADE_SUCCESS（交易支付成功）
        # TRADE_FINISHED（交易结束，不可退款）

        try:
            aliPayObj = AliPayObject()
            alipay = aliPayObj.conf()
            result = alipay.api_alipay_trade_query(out_trade_no=order.orderID)
            print(result)

            if result['code'] == '100000':
                trade_status = result['trade_status']
                if trade_status == 'TRADE_CLOSED' or trade_status == 'WAIT_BUYER_PAY':
                    order.status = 2
                    order.updTime = int(time.time())
                    order.save()
                    return response.json(0)
                elif trade_status == 'TRADE_SUCCESS':
                    order.status = 1
                    order.updTime = int(time.time())
                    order.save()
                    return response.json(802)
            elif result['code'] == '40004':
                order.status = 2
                order.updTime = int(time.time())
                order.save()
                return response.json(0)
            else:
                return response.json(10, result['sub_msg'])

        except Exception as e:
            print(repr(e))
            return response.json(10, repr(e))

    def do_cancel_paypal_order(self, order, response):
        paypalrestsdk.configure(PAYPAL_CRD)
        payment = paypalrestsdk.Payment.find(order.trade_no)
        transactions = payment['transactions']
        transaction = transactions[0]
        related_resources = transaction['related_resources']
        if len(related_resources) > 0:
            related_resource = related_resources[0]
            sale = related_resource['sale']
            if sale['state'] == 'completed':
                order.status = 1
            elif sale['state'] == 'refunded':
                order.status = 3

            order.updTime = int(time.time())
            order.save()
            return response.json(802)

        order.status = 2
        order.updTime = int(time.time())
        order.save()
        return response.json(0)