#coding=utf-8

from django.db import models
from django.utils import timezone

from apps.customer.models import Customer
from apps.product_order.models import ProductOrder
from apps.foundation.models import Config
from apps.customer.models import CustomerWechat

from utils.exceptions import CustomError
from utils.wechatpay import WechatPay

class Pay(models.Model):
    WAIT = 1
    CONFIRM = 2
    CLOSED = 3
    STATUS_CHOICES = (
        (WAIT, u'待付款'),
        (CONFIRM, u'已付款'),
        (CLOSED, u'已关闭'),
    )
    no = models.CharField(max_length=64, verbose_name=u"单号")
    create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now)
    customer = models.ForeignKey(Customer, verbose_name=u'客户', on_delete=models.PROTECT)
    status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, verbose_name=u"支付状态")
    precreate_amount = models.BigIntegerField(verbose_name=u"预支付金额")
    amount = models.BigIntegerField(verbose_name=u"实际支付金额", null=True)

    class Meta:
        db_table = "pay"
        verbose_name = u"支付"
        ordering = ('-id',)
        index_together = (
            'create_time',
            'status',
        )
        unique_together = (
            'no',
        )
        default_permissions = ()

    def payClosed(self):
        if self.status != Pay.WAIT:
            return

        self.status = Pay.CLOSED
        self.save()
        self.updateOrderStatus(ProductOrder.REVOKE)

    def payConfirm(self, amount):
        if self.status != Pay.WAIT:
            return

        self.status = Pay.CONFIRM
        self.amount = amount
        self.save()
        self.updateOrderStatus(ProductOrder.PAID)

    def updateOrderStatus(self, status):
        pay_order = PayProduct.objects.filter(main=self).first()
        pay_order.order.status = status
        pay_order.order.save()

    @staticmethod
    def getByNo(no):
        instance = Pay.objects.filter(no=no).first()
        if not instance:
            raise CustomError(u'未找到相应的支付单！')
        return instance

    @staticmethod
    def wechatPay(customer, amount, openid):
        instance = Pay._addnew(customer,  amount)
        return instance, instance._wechatUnifiedOrder(openid)

    @staticmethod
    def _addnew(customer,  amount):
        if amount <= 0:
            raise CustomError(u'无效的付款金额！')

        no = timezone.now().strftime('%y%m%d%H%M%S') + str(customer.id)
        instance = Pay.objects.create(
            no=no,
            customer=customer,
            status=Pay.WAIT,
            precreate_amount=amount
        )
        return instance

    def _wechatUnifiedOrder(self, openid):
        wechat_appid = Config.getConfigValue(Config.KEY_WECHAT_APPID)
        tenant_num = Config.getConfigValue(Config.KEY_WECHAT_TENANT_NUM)
        tenant_key = Config.getConfigValue(Config.KEY_WECHAT_TENANT_KEY)
        wechatpay = WechatPay(wechat_appid, tenant_num, tenant_key)
        wechatpay.unifiedOrder(self.no, self.precreate_amount, openid)
        data = wechatpay.getAppString()
        return data


class PayProduct(models.Model):
    main = models.OneToOneField(Pay, verbose_name=u'支付单', on_delete=models.PROTECT, related_name='pay_product_pay')
    order = models.OneToOneField(ProductOrder, verbose_name=u'商品订单', on_delete=models.PROTECT, related_name='pay_product_order')

    class Meta:
        db_table = "pay_product"
        verbose_name = u"支付商品"
        ordering = ('-id',)
        default_permissions = ()

    @staticmethod
    def addnew(order, openid):
        pay, query_string = Pay.wechatPay(order.customer, order.amount, openid)
        instance = PayProduct.objects.create(main=pay, order=order)
        return instance, query_string


