# coding:utf-8
""" 微信支付宝支付轮询 """

import requests
from datetime import datetime
from yattag import Doc
from django.conf import settings
from django.core.management.base import BaseCommand
from gm_types.gaia import PAYMENT_CHANNEL, ORDER_STATUS, GROUPBUY_STATUS
from gm_types.pay import REFUND_CODE
from pay.models.wechat import XML, random_str, Wechat, WechatSettlement
from pay.models.alipay import AlipaySettlement
from pay.tool.purchase_tool import order_paid
from pay.tool.purchase_tool import after_settlement_paid
from pay.tool.alipay_tool import AlipayTool
from api.models import SettlementItem, Order
from api.tool.log_tool import logging_exception


ORDER_QUERY_URL = "https://api.mch.weixin.qq.com/pay/orderquery"


def need_query_order():
    now = datetime.now()
    today = datetime(now.year, now.month, now.day, 0, 0, 0)
    objs = Order.objects.filter(status__in=(ORDER_STATUS.NOT_PAID, ORDER_STATUS.PAYING), created_time__gt=today).values('id')
    ids = [obj['id'] for obj in objs]
    print('need deal order ids is ', ids)
    return ids


def get_order_transaction_id(order_id):
    settlement_obj = SettlementItem.objects.get(order_id=order_id)
    settlement_id = settlement_obj.settlement.id
    try:
        wechat_settlement = WechatSettlement.objects.get(settlement_id=settlement_id)
        return wechat_settlement.transaction_id
    except:
        pass

    try:
        alipay_settlement = AlipaySettlement.objects.get(settlement_id=settlement_id)
        return alipay_settlement.transaction_id
    except:
        pass


def wechat_order_query(wechat_obj, transaction_id):
    url = ORDER_QUERY_URL
    noncestr = random_str()
    data = {
        "appid": wechat_obj.app_id,
        "mch_id": wechat_obj.mch_id,
        "nonce_str": noncestr,
        "transaction_id": transaction_id,
    }
    sign = wechat_obj.sign(data)
    doc, tag, text = Doc().tagtext()
    with tag("xml"):
        with tag("appid"):
            text(data["appid"])
        with tag("mch_id"):
            text(data["mch_id"])
        with tag("nonce_str"):
            text(data["nonce_str"])
        with tag("sign"):
            text(sign)
        with tag("transaction_id"):
            text(data["transaction_id"])
    xml_data = doc.getvalue()
    r = requests.post(url, data=xml_data)
    text = r.text.encode("ISO-8859-1")
    root = XML(text)
    result_code = root.cdata("result_code")
    print(result_code)
    return root.cdata("trade_state")


def update_order_status(order_id, payment_channel):
    # order_id, settlement_id, 为要处理的订单及计算单
    order = Order.objects.get(id=order_id)
    auto_create_diary = True or False
    # 调用 order_paid方法生成验证码及状态变更
    order_paid(
        order=order,
        payment_channel=payment_channel,
        pay_time=datetime.now(),
        auto_create_diary=auto_create_diary
    )

    relation = SettlementItem.objects.get(order_id=order_id)
    settlement = relation.settlement
    try:
        after_settlement_paid(settlement)
    except Exception as e:
        logging_exception(e)
        order = Order.objects.get(id=order_id)
        join_groupbuy_team_id = order.join_groupbuy_team_id
        team_count = Order.objects.filter(
            status__in=(ORDER_STATUS.PAID, ORDER_STATUS.USED), join_groupbuy_team_id=join_groupbuy_team_id).count()
        if team_count == 2 and order.groupbuy_status == GROUPBUY_STATUS.GROUPBUY_STARTED:
            Order.objects.filter(
                id=order_id, join_groupbuy_team_id=join_groupbuy_team_id).update(
                groupbuy_status=GROUPBUY_STATUS.GROUPBUY_SUCCESSED)


def deal_wechat_order(order_id):
    transaction_id = get_order_transaction_id(order_id)
    try:
        wechat_obj = Wechat(settings.NEW_CLIENT_WECHAT_APP_ID, settings.NEW_CLIENT_WECHAT_PARTNER_ID,
                            settings.NEW_CLIENT_WECHAT_SECRET)
        query_result = wechat_order_query(wechat_obj, transaction_id)
        if query_result != 'SUCCESS':
            print('wechat order_id {} has not paid!'.format(order_id))
        else:
            print('wechat order_id {} has paid!'.format(order_id))
            update_order_status(order_id, PAYMENT_CHANNEL.WECHAT)
    except:
        print('wechat order_id {} is not exist'.format(order_id))


def alipay_order_query(trade_no, out_trade_no):
    code = AlipayTool.query(
        pid=settings.ALIPAY_USING_PARTNER, out_trade_no=out_trade_no, trade_no=trade_no)
    if code:
        return True
    return False


def deal_alipay_order(order_id):
    transaction_id = get_order_transaction_id(order_id)
    try:

        query_result = alipay_order_query(transaction_id)
        if query_result:
            print('alipay order_id {} has not paid!'.format(order_id))
        else:
            print('alipay order_id {} has paid!'.format(order_id))
            update_order_status(order_id, PAYMENT_CHANNEL.ALIPAY)
    except:
        print('alipay order_id {} is not exist'.format(order_id))


class Command(BaseCommand):

    def handle(self, *args, **options):
        print('start deal: ', datetime.now())
        order_ids = need_query_order()

        for order_id in order_ids:
            print('order_id is {}  start deal!'.format(order_id), datetime.now())
            deal_wechat_order(order_id)
            deal_alipay_order(order_id)
            print('order_id is {}  end deal!'.format(order_id), datetime.now())

        print('end deal: ', datetime.now())
