# coding=utf-8
import traceback
from django.db.models import Sum, F
from rest_framework.decorators import action
from rest_framework.views import APIView
from utils.file_operation import attachment_save
from django.db import transaction
from django.db.models import Q
from utils.custom_modelviewset import CustomModelViewSet
from .serializers import *
from .filters import *
from .resources import *
from apps.log.models import BizLog
from apps.base import Formater
from utils import response_ok, response_error
from utils.permission import isLogin, permission_required
from apps.order.models import Order
from apps.WeChatResponse import WechatAppletPay, WeChatResponse
from django.contrib.auth import get_user_model
User = get_user_model()


class OrderViewSet(CustomModelViewSet):
    permission_classes = [isLogin, ]
    queryset = Order.objects.filter()
    serializer_class = OrderSerializer

    def list(self, request, *args, **kwargs):
        # 底栏合计
        export = request.GET.get('export')

        queryset = self.filter_queryset(self.get_queryset())
        if export:
            queryset = queryset.filter(status=Order.FINISH).order_by('-student__classes_id',
                                                                     '-student__classes__grade_id')
            export_data = OrderResource().export(queryset)
            filename = attachment_save(export_data, '用户订单{}'.format(timezone.now().date()))

            return response_ok({'filename': filename})
        total = queryset.aggregate(total_amount=Sum('total_amount'), coupon_deduction=Sum('coupon_deduction'),
                                   actual_amount=Sum('actual_amount'))
        totalRow = {'totalRow': 1,
                    'total_amount': Formater.formatPriceShow(total['total_amount']),
                    'coupon_deduction': Formater.formatPriceShow(total['coupon_deduction']),
                    'actual_amount': Formater.formatPriceShow(total['actual_amount'], )}
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            data = serializer.data
            if len(data) > 0:
                data.append(totalRow)
            return self.get_paginated_response(data)

        serializer = self.get_serializer(queryset, many=True)
        return response_ok(serializer.data)

    def filter_queryset(self, queryset):
        queryset = queryset.filter()
        if self.request.user.type == User.CUSTOMER:
            queryset = queryset.filter(create_user=self.request.user)
        elif self.request.user.type == User.AGENT:
            # 代理商，筛选代理的类别和学校
            queryset = queryset.filter(
                Q(commodity__category__in=self.request.user.category) | Q(student__school=self.request.user.school))

        f = OrderFilter(self.request.GET, queryset=queryset)
        return f.qs

    def create(self, request, *args, **kwargs):
        commodity_id = request.POST.get('commodity')
        openid = request.POST.get('openid')
        appid = request.POST.get('appid')
        coupon = request.POST.get('coupon')
        count = request.POST.get('count')

        try:
            # if request.user.id != 17 and  request.user.id != 18:
            #     raise CustomError(u'系统升级中，请稍后再试！')
            count = int(count)
            commodity = Commodity.objects.filter(id=commodity_id, status=settings.ONLINE, stock__gte=count).first()
            if not commodity:
                raise CustomError(u'当前商品库存不足！')

            with transaction.atomic():
                serializer = self.get_serializer(data=request.data)
                if serializer.is_valid(raise_exception=True):
                    instance = serializer.save()

                    instance.total_amount = count * commodity.price * commodity.discount / 100
                    actual_amount = instance.total_amount
                    if coupon:
                        coupon = Coupon.objects.filter(id=coupon).first()
                        actual_amount -= coupon.amount
                        instance.coupon = coupon

                    data = ''
                    if actual_amount:
                        # 小程序在线支付
                        pay = Pay.wechatAppPay(self.request.user, actual_amount, Pay.CUSTOMER)
                        wechatpay = WechatAppletPay(appid)
                        data = wechatpay.weChatUnifiedOrder(openid, pay.pay_no,
                                                            Formater.formatPriceShow(actual_amount))
                        instance.pay = pay
                    instance.save()
                    commodity.stock -= count
                    commodity.save()
                    BizLog.objects.addnew(self.request.user, BizLog.INSERT,
                                          u'添加订单[%s]，id=%d' % (instance.no, instance.id), request.data)
                    return response_ok(data)
        except CustomError as e:
            return response_error(e.get_error_msg())
        except Exception as e:
            import traceback
            traceback.print_exc()
            return response_error(str(e))

    @action(methods=['post'], detail=True)
    def pay_order(self, request, pk):
        # 待付款订单付款
        openid = request.POST.get('openid')
        appid = request.POST.get('appid')
        data = {}
        try:
            instance = self.get_object()
            with transaction.atomic():
                total_amount = instance.total_amount
                if instance.status != Order.WAIT_PAY:
                    raise CustomError('订单非待付款状态，禁止付款！')
                if instance.pay:
                    pay_no = instance.pay.pay_no
                    # 先查询订单状态
                    checkRexponse = WeChatResponse(appid)
                    total_fee = checkRexponse.orderquery(pay_no)
                    if int(total_fee) == int(total_amount):
                        wechatpay = WechatAppletPay(appid)
                        data = wechatpay.weChatUnifiedOrder(openid, pay_no,
                                                            Formater.formatPriceShow(total_amount))
                        return response_ok(data)
                    # 支付金额变动后，关闭原订单，重新发起支付
                    instance.pay.payClosed()
                pay = Pay.wechatAppPay(self.request.user, total_amount)
                wechatpay = WechatAppletPay(appid)
                data = wechatpay.weChatUnifiedOrder(openid, pay.pay_no,
                                                    Formater.formatPriceShow(total_amount))
                instance.pay = pay
                instance.save()
            return response_ok(data)
        except CustomError as e:
            return response_error(e.get_error_msg())
        except Exception as e:
            return response_error(str(e))


class ExportOrderDictView(APIView):
    permission_classes = [isLogin]

    def get(self, request):
        queryset = Order.objects.filter(status=Order.FINISH).order_by('-student__classes_id',
                                                                      '-student__classes__grade_id')
        export_data = OrderResource().export(queryset)
        filename = attachment_save(export_data, '用户订单{}'.format(timezone.now().date()))

        return response_ok({'filename': filename})


class WXGetCoupon(APIView):
    permission_classes = [isLogin]

    def get(self, request):
        commodity_id = request.GET.get('commodity')
        student_id = request.GET.get('student')
        commodity = Commodity.objects.filter(id=commodity_id).first()
        data = {
            'coupon_name': '',
            'coupon_amount': 0,
        }
        if not commodity:
            return response_ok(data)
        student = Student.objects.filter(id=student_id).first()
        coupons = Coupon.objects.filter(enable=True, begin_date__lte=timezone.now().date(),
                                        end_date__gte=timezone.now().date())
        for coupon in coupons:
            if coupon.category:
                categorys = coupon.category.split(',')
                if commodity.category and str(commodity.category.id) in categorys:
                    data = {
                        'coupon_id': coupon.id,
                        'coupon_name': coupon.name,
                        'coupon_amount': Formater.formatPriceShow(coupon.amount),
                    }
                    return response_ok(data)
            if student and coupon.school:
                schools = coupon.school.split(',')
                if str(student.school.id) in schools:
                    data = {
                        'coupon_id': coupon.id,
                        'coupon_name': coupon.name,
                        'coupon_amount': Formater.formatPriceShow(coupon.amount),
                    }
                    return response_ok(data)
        return response_ok(data)

class ShoppingCartViewSet(CustomModelViewSet):
    permission_classes = [isLogin]
    queryset = ShoppingCart.objects.filter()
    serializer_class = ShoppingCartSerializer

    def filter_queryset(self, queryset):
        queryset = queryset.filter(create_user=self.request.user)
        return queryset

    @action(methods=['post'], detail=True)
    def modify_quantity(self, request, pk):
        quantity = self.request.POST.get('quantity')

        try:
            with transaction.atomic():
                instance = ShoppingCart.objects.filter(id=pk, create_user=self.request.user).first()
                if instance:
                    instance.quantity = quantity
                    instance.save()
            return response_ok()
        except CustomError as e:
            return response_error(e.get_error_msg())
        except Exception as e:
            traceback.print_exc()
            return response_error(str(e))

    @action(methods=['post'], detail=False)
    def del_shopping_carts(self, request):
        item = request.POST.get('ids').split(',')
        try:
            with transaction.atomic():
                ShoppingCart.objects.filter(id__in=item, create_user=self.request.user).delete()
            return response_ok()
        except CustomError as e:
            return response_error(e.get_error_msg())
        except Exception as e:
            traceback.print_exc()
            return response_error(str(e))


class CouponViewSet(CustomModelViewSet):
    permission_classes = [isLogin]
    queryset = Coupon.objects.filter()
    serializer_class = CouponSerializer

    @permission_required('order.view_coupon')
    def filter_queryset(self, queryset):
        queryset = queryset.filter(create_user=self.request.user)
        return queryset
