#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
#   Author  :   zhangxiaolin
#   E-mail  :   petelin1120@gmail.com
#   Date    :   17/10/18 16:01
#   Desc    :   迁移工具类
import json
from xml.etree import ElementTree

from gm_types.pay import CHANNEL
from django.db import transaction

from api.models import Order
from pay.manager.purchase_manager import ConvertNotifyData
from pay.models import PaymentOrder, ApplePaySettlement, PaymentOrderItem, WechatOrder


def lianlian():
    f = ApplePaySettlement.objects.all().order_by('id')
    wait_trans_count = f.count()
    print "等待迁移 ", wait_trans_count

    dc = 0
    for i in range(0, wait_trans_count, 500):
        for apple_settlement in f[i: i+500]:
            with transaction.atomic():
                notify_data_dict = {
                    "_migrate_from": "pay_applepaysettlement",
                    "settlement_id": apple_settlement.settlement_id,
                    "oid_partner": apple_settlement.oid_partner,
                    "dt_order": apple_settlement.dt_order.strftime('%Y-%m-%d %H:%M:%S'),
                    "created_time": apple_settlement.created_time.strftime('%Y-%m-%d %H:%M:%S.%f'),
                    "oid_paybill": apple_settlement.oid_paybill,
                    "money_order": apple_settlement.money_order,
                }
                notify_data = json.dumps(notify_data_dict)

                payment_order, create = PaymentOrder.objects.get_or_create(
                    transaction_id=apple_settlement.oid_paybill,
                    defaults=dict(
                        total_fee=int(apple_settlement.money_order * 100),
                        channel=CHANNEL.LIANLIAN,
                        out_trade_no=apple_settlement.settlement_id,
                        pay_start_time=notify_data_dict['created_time'],
                        paid_time=notify_data_dict['created_time'],
                        account_seller_id=apple_settlement.oid_partner,
                        notify_data=notify_data,
                    )
                )
                if not create:
                    continue
                for settlement_item in apple_settlement.settlement.items.all():
                    PaymentOrderItem.objects.create(payment_order=payment_order, order=settlement_item.order)

                dc+=1
                print "lianlian transaction_id {}: {}".format(dc,apple_settlement.oid_paybill)


def wechat():
    f = WechatOrder.objects.filter(created_time__lte='2017-11-10')
    wait_trans_count = f.count()
    batch_count = 100
    print "需要迁移 ", wait_trans_count
    for i in range(0, wait_trans_count, batch_count):
        for wechat_order in f[i:i + batch_count]:
            orders = list(Order.objects.filter(id=wechat_order.order_no).values_list('id', 'pay_time'))
            if len(orders) == 0:
                print 'not fund order: ', wechat_order.order_no
                continue

            order_id = orders[0][0]
            order_pay_time = orders[0][1]

            try:
                payment_order = PaymentOrder.objects.get(out_trade_no=wechat_order.out_trade_no)
            except PaymentOrder.DoesNotExist:
                pass
            else:
                PaymentOrderItem.objects.get_or_create(payment_order=payment_order, order_id=order_id)
                continue

            notify_data_dict = {
                "_migrate_from": "pay_wechatorder",
                "order_id": wechat_order.order_no,
                "appid": wechat_order.appid,
                "bank_type": wechat_order.bank_type,
                "cash_fee": wechat_order.cash_fee,
                "fee_type": wechat_order.fee_type,
                "is_subscribe": wechat_order.is_subscribe,
                "mch_id": wechat_order.mch_id,
                "nonce_str": wechat_order.nonce_str,
                "openid": wechat_order.openid,
                "out_trade_no": wechat_order.out_trade_no,
                "result_code": wechat_order.result_code,
                "sign": wechat_order.sign,
                "total_fee": wechat_order.total_fee,
                "time_end": wechat_order.time_end,
                "trade_type": wechat_order.trade_type,
                "transaction_id": wechat_order.transaction_id,
                "created_time": wechat_order.created_time.strftime('%Y-%m-%d %H:%M:%S'),
            }
            notify_data = json.dumps(notify_data_dict)

            payment_order = PaymentOrder()
            payment_order.total_fee = wechat_order.cash_fee
            payment_order.channel = CHANNEL.WECHAT
            payment_order.out_trade_no = wechat_order.out_trade_no
            payment_order.transaction_id = wechat_order.transaction_id
            payment_order.pay_start_time = order_pay_time
            payment_order.paid_time = order_pay_time
            # 账号相关, 因为退款需要知道账号信息. 退款也迁移过去就不需要了.
            payment_order.account_seller_id = wechat_order.appid
            payment_order.notify_data = notify_data
            payment_order.save()

            PaymentOrderItem.objects.get_or_create(payment_order=payment_order, order_id=order_id)


def alipay():
    order_ids = list(
        Order.objects.filter(trade_no__isnull=False, created_time__lte='2017-11-10').values_list('id', flat=True))
    wait_trans_count = len(order_ids)
    batch_count = 100

    print "需要迁移 ", wait_trans_count
    for i in range(0, wait_trans_count, batch_count):
        orders = list(Order.objects.filter(id__in=order_ids[i:i + batch_count]))
        for order in orders:
            try:
                if order.trade_no is None or order.trade_no == '':
                    continue
                if order.origin_data is not None and order.origin_data.startswith('<notify>'):
                    json_data = ElementTree.fromstring(order.origin_data.encode('utf-8'))
                    ElementTree.SubElement(json_data, '_migrate_from_order')
                else:
                    json_data = json.loads(order.origin_data)
                    if 'notify_data' in json_data:
                        json_data = ElementTree.fromstring(json_data['notify_data'].encode('utf-8'))
                        ElementTree.SubElement(json_data, '_migrate_from_order')
                    else:
                        json_data['_migrate_from_order'] = ''

                trade_data = ConvertNotifyData(json_data)
                PaymentOrder.objects.save_from_ali(order, trade_data)
            except Exception as e:
                print order.id, order.origin_data
                print e


def check_alipay():
    from pay.models import PaymentOrderItem, PaymentOrder
    from api.models import Order

    order_ids = list(
        Order.objects.filter(trade_no__isnull=False).values_list('id', 'trade_no'))
    wait_trans_count = len(order_ids)
    batch_count = 500

    print u"需要校验 ", wait_trans_count
    for i in range(0, wait_trans_count, batch_count):
        orders = order_ids[i:i + batch_count]
        order_ids = [oid for oid, no in orders]

        pp_2_no = {oid: no for oid, no in
                   PaymentOrderItem.objects.filter(order_id__in=order_ids).values_list('order_id',
                                                                                       'payment_order__transaction_id')}

        for oid, no in orders:
            if oid not in pp_2_no or pp_2_no[oid] != no:
                print("error : {}".format(oid))
            else:
                print("ok : {}".format(oid))


def check_wechat():
    from pay.models import PaymentOrderItem, PaymentOrder, WechatOrder

    order_ids = list(
        WechatOrder.objects.filter(order_no__isnull=False).values_list('order_no', 'transaction_id', 'total_fee'))
    wait_trans_count = len(order_ids)
    batch_count = 500

    print u"需要校验 ", wait_trans_count
    for i in range(0, wait_trans_count, batch_count):
        print ("i: {}".format(i))
        orders = order_ids[i:i + batch_count]
        order_ids = [oid for oid, no, fee in orders]

        pp_2_no = {oid: (no, fee) for oid, no, fee in
                   PaymentOrderItem.objects.filter(order_id__in=order_ids).values_list('order_id',
                                                                                       'payment_order__transaction_id',
                                                                                       'payment_order__total_fee')}

        for oid, no, fee in orders:
            if oid not in pp_2_no or pp_2_no[oid] != (no, fee):
                print("error : {}".format(oid))


def copy_coupon_data():
    from pay.models import ServiceSnapshot
    from api.models import Coupon, OrderCouponInfo

    ss_data = list(ServiceSnapshot.objects.filter(coupon_info_id__gt=0))

    coupon_id_to_value = {}

    for ss in ss_data:
        if ss.coupon_info_id > 0:
            order_id = ss.order_id

            already_has = OrderCouponInfo.objects.filter(
                order_id=order_id, coupon_info_id=ss.coupon_info_id).exists()

            if already_has:
                print ("oid 【{}】 ciid: 【{}】already_has".format(order_id, ss.coupon_info_id))
                continue

            if ss.coupon_info:
                ooi = OrderCouponInfo()

                ooi.order_id = order_id

                ci_dict = json.loads(ss.coupon_info)

                coupon_id = ci_dict['coupon_id']
                platform_coupon_deduction = ci_dict['coupon_value']
                doctor_coupon_deduction = ci_dict['doctor_coupon_deduction']

                if coupon_id not in coupon_id_to_value:
                    value = -1
                    if not coupon_id:
                        print ("coupon_id:{} not exists".format(coupon_id))
                        continue

                    c = Coupon.objects.filter(id=coupon_id).first()
                    if not c:
                        print ("coupon_id:{} not exists".format(coupon_id))
                    coupon_id_to_value[coupon_id] = c.value if c else value

                ooi.coupon_id = coupon_id
                ooi.coupon_info_id = ci_dict['coupon_info_id']
                ooi.coupon_name = ci_dict['coupon_name']
                ooi.coupon_value = coupon_id_to_value[coupon_id]
                ooi.coupon_type = ci_dict['coupon_type']

                ooi.platform_coupon_deduction = platform_coupon_deduction
                ooi.coupon_gengmei_percent = ci_dict['coupon_gengmei_percent']
                ooi.coupon_gengmei_value = ci_dict['coupon_gengmei_value']
                ooi.coupon_doctor_value = ci_dict['coupon_doctor_value']

                ooi.doctor_coupon_deduction = doctor_coupon_deduction

                ooi.save()
                ci_dict = None
            else:
                ooi = OrderCouponInfo()

                ooi.order_id = order_id

                coupon_id = ss.coupon_id

                if coupon_id not in coupon_id_to_value:
                    value = -1
                    if not coupon_id:
                        print ("coupon_id:{} not exists".format(coupon_id))
                        continue
                    c = Coupon.objects.filter(id=coupon_id).first()
                    if not c:
                        print ("coupon_id:{} not exists".format(coupon_id))
                    coupon_id_to_value[coupon_id] = c.value if c else value

                ooi.coupon_id = ss.coupon_id
                ooi.coupon_info_id = ss.coupon_info_id
                ooi.coupon_name = ss.coupon_name
                ooi.coupon_value = coupon_id_to_value[coupon_id]
                ooi.coupon_type = ss.coupon_type

                ooi.platform_coupon_deduction = ss.coupon_value
                ooi.coupon_gengmei_percent = ss.coupon_gengmei_percent
                ooi.coupon_gengmei_value = ss.coupon_gengmei_value
                ooi.coupon_doctor_value = ss.coupon_doctor_value

                ooi.doctor_coupon_deduction = 0

                ooi.save()

            print ("oid 【{}】 ciid: 【{}】finish".format(order_id, ss.coupon_info_id))

    print ("FINISH !!")


def check_coupon_data():
    from pay.models import ServiceSnapshot
    from api.models import Coupon, OrderCouponInfo
    from gm_types.gaia import COUPON_TYPES

    ss_data = list(ServiceSnapshot.objects.filter(coupon_info_id__gt=0))

    for ss in ss_data:
        if ss.coupon_info_id > 0:
            order_id = ss.order_id

            oci_list = list(
                OrderCouponInfo.objects.filter(order_id=order_id, coupon_info_id=ss.coupon_info_id)
            )

            if len(oci_list) != 1:
                print ("oid 【{}】 ciid: 【{}】oci_list !=1 ! len:{}".format(order_id, ss.coupon_info_id, len(oci_list)))
                continue

            oci = oci_list[0]

            all_match = oci.coupon_id == ss.coupon_id and oci.coupon_info_id == ss.coupon_info_id and oci.coupon_name == ss.coupon_name and oci.platform_coupon_deduction == ss.coupon_value and oci.coupon_type == ss.coupon_type and oci.coupon_gengmei_percent == ss.coupon_gengmei_percent and oci.coupon_gengmei_value == ss.coupon_gengmei_value and oci.coupon_doctor_value == ss.coupon_doctor_value

            if ss.coupon_info:
                d = json.loads(ss.coupon_info)
                doctor_coupon_deduction = d['doctor_coupon_deduction']
                all_match = all_match and doctor_coupon_deduction == oci.doctor_coupon_deduction

            if not all_match:
                print ("oid 【{}】 ciid: 【{}】not all_match".format(order_id, ss.coupon_info_id, len(oci_list)))

    print ("FINISH !!")
