# coding=utf-8

import json
import datetime
import traceback

from django.db import transaction
from django.db.models import Q, F
from django.utils import timezone

from rest_framework.decorators import action
from rest_framework import generics

from utils import response_ok, response_error
from utils.exceptions import CustomError
from utils.permission import IsCustomer
from utils.custom_modelviewset import CustomModelViewSet
from utils.wechatpay import WeChatResponse
from apps.order.models import ShoppingCart, Order, Pay
from apps.order.filters import ShoppingCartFilter, OrderFilter
from apps.customer.order.serializers import ShoppingCartSerializer, OderSerializer, OderSimpleSerializer
from apps.customer.models import Customer
from apps.rebate.models import PointLogOrder
from apps.log.models import BizLog


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

    def filter_queryset(self, queryset):
        queryset = queryset.filter(customer=self.request.customer)
        f = ShoppingCartFilter(self.request.GET, queryset=queryset)
        return f.qs

    def perform_create(self, serializer):
        super(ShoppingCartViewSet, self).perform_create(serializer)

    @action(methods=['post'], detail=True)
    def update_quantity(self, request, pk):
        quantity = request.POST.get('quantity')
        try:
            quantity = int(quantity)
        except:
            raise CustomError(u'商品数量错误，请修改！')
        if quantity <= 0:
            raise CustomError(u'请输入正确的商品数量！')
        with transaction.atomic():
            instance = ShoppingCart.objects.filter(id=pk, customer=request.customer).first()
            if instance:
                instance.quantity = quantity
                instance.save()
        return response_ok()

    @action(methods=['post'], detail=False)
    def del_cart(self, request):
        car_ids = json.loads(request.data.get('ids'))
        with transaction.atomic():
            ShoppingCart.objects.filter(id__in=car_ids, customer=request.customer).delete()
        return response_ok()


class OrderListView(generics.ListAPIView):
    permission_classes = [IsCustomer, ]
    queryset = Order.objects.filter()
    serializer_class = OderSimpleSerializer

    def filter_queryset(self, queryset):
        queryset = queryset.filter(customer=self.request.customer)
        try:
            # 将本人待支付且过期的订单改为取消状态
            end_time = timezone.now() - datetime.timedelta(minutes=10)
            rows = queryset.filter(status=Order.WAIT_PAY, create_time__lte=end_time)
            with transaction.atomic():
                for row in rows:
                    # 如果订单改为取消状态将订单积分返还，因为下单的时候积分已经被扣除了
                    if row.total_point > 0:
                        PointLogOrder.addnew(row, cancel_order=True)
                rows.update(status=Order.CANCEL, cancel_time=timezone.now(), cancel_reason='订单过期失效，自动取消。')
        except Exception as e:
            traceback.print_exc()

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


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

    def create(self, request, *args, **kwargs):
        '''
        创建订单
        :param request:
        :param args:
        :param kwargs:
        :return:
        '''
        openid = request.POST.get('openid')
        appid = request.POST.get('appid')
        address_id = request.POST.get('address_id', None)
        details = json.loads(request.POST.get('details'))
        if not address_id:
            raise CustomError(u'请选择收货地址！')
        with transaction.atomic():
            serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            serializer.save()
            order = serializer.instance
            order.generateNo()
            # 用户收货地址
            order.set_order_adderss(address_id)
            # 订单详细
            order.set_order_detail(details)
            # 订单支付
            data = ''
            if order.total_amount <= 0 and order.total_point <= 0:
                raise CustomError(u'无效的付款金额')
            # 下单时如果有积分，直接扣掉积分。如果没有支付或支付失败 取消订单还原积分
            if order.total_point > 0:
                PointLogOrder.addnew(order)
            if order.total_amount > 0:
                pay, data = Pay.wechatPay(order.total_amount, self.request.customer, appid, openid)
                order.pay = pay
            # 没有支付现金的积分也扣过了  直接修改订单状态  如果有现金支付的 通过微信支付回调修改订单状态
            if not order.pay:
                order.pointConfirm()
            order.save()
            BizLog.objects.addnew(self.request.user, BizLog.INSERT, u'添加订单[%s]，id=%d' % (order.no, order.id), request.data)
        return response_ok(data)

    @action(methods=['post'], detail=True)
    def pay_order(self, request, pk):
        '''
        待支付订单支付  在订单管理 待支付 订单直接支付(由于积分商品在下单的时候积分都已经扣过了  在这就不在扣除积分了)
        :param request:
        :param pk:
        :return:
        '''
        openid = request.POST.get('openid')
        appid = request.POST.get('appid')

        order = self.get_object()
        if not openid or not appid:
            raise CustomError(u'参数错误！')
        with transaction.atomic():
            # 如果订单过期了  就不能再支付了
            end_time = order.create_time + datetime.timedelta(minutes=10)
            if timezone.now() >= end_time:
                raise CustomError(u'该订单已过期，请重新下单！')
            data = order.orderPay(openid, appid)
        return response_ok(data)
