from dg_sdk.module.request_tools import request_post, online_payment_create, online_payment_close, \
    online_payment_query, online_payment_refund, online_payment_refund_query, offline_payment_scan, \
    request_post_without_seq_id, online_payment_close_query
from dg_sdk.common_util import generate_mer_order_id


class ScanPayment(object):
    """
    聚合正扫，聚合反扫，交易查询，交易退款，退款查询，关单
    """

    @classmethod
    def create(cls, trade_type, trans_amt, goods_desc, *, open_id="", app_id="", buyer_id="",
               user_id="", client_ip="", **kwargs):
        """
        创建聚合正扫订单
        :param trade_type: 微信公众号-T_JSAPI 小程序-T_MINIAPP 支付宝JS-A_JSAPI 支付宝正扫-A_NATIVE 银联正扫-U_NATIVE
        银联JS-U_JSAPI 数字货币二维码支付-D_NATIVE
        :param trans_amt: 交易金额，单位为元，（例如：100.00）
        :param goods_desc: 商品描述
        :param open_id: 微信 open_id
        :param app_id: 微信 app_id（小程序或者公众号）
        :param buyer_id: 支付宝买家ID
        :param user_id: 银联用户标识
        :param client_ip: 付款时的IP地址，银联JS支付必填
        :param kwargs:  额外参数
        :return: 支付对象
        """

        required_params = {
            "trade_type": trade_type,
            "trans_amt": trans_amt,
            "goods_desc": goods_desc,
        }

        # 微信公众号：T_JSAPI；小程序：T_MINIAPP
        if trade_type == "T_JSAPI" or trade_type == "T_MINIAPP":
            if not kwargs.get("wx_data"):
                kwargs["wx_data"] = {
                    "sub_appid": app_id,
                    "sub_openid": open_id
                }

        # 支付宝JS
        if trade_type == "A_JSAPI":
            if not kwargs.get("alipay_data"):
                kwargs["alipay_data"] = {
                    "buyer_id": buyer_id
                }

        # 银联正扫：U_NATIVE；银联JS：U_JSAPI
        if trade_type == "U_NATIVE" or trade_type == "U_JSAPI":
            if not kwargs.get("unionpay_data"):
                kwargs["unionpay_data"] = {
                    "user_id": user_id,
                    "client_ip": client_ip
                }
            kwargs["user_id"] = user_id
        if not kwargs.get("mer_ord_id"):
            kwargs["mer_ord_id"] = generate_mer_order_id()

        required_params.update(kwargs)

        return request_post(online_payment_create, required_params)

    @classmethod
    def scan_pay(cls, trans_amt, goods_desc, auth_code, **kwargs):
        """
        聚合反扫
        :param trans_amt: 交易金额
        :param goods_desc: 商品描述
        :param auth_code: 支付码
        :param kwargs: 额外参数
        :return: 支付结果
        """
        required_params = {
            "auth_code": auth_code,
            "trans_amt": trans_amt,
            "goods_desc": goods_desc,
        }

        # TODO 确认风控信息
        if not kwargs.get("risk_check_info"):
            kwargs["risk_check_info"] = ""

        required_params.update(kwargs)
        return request_post(offline_payment_scan, required_params)

    @classmethod
    def query(cls, org_req_date, *, org_req_seq_id="", org_hf_seq_id="", party_order_id="", out_trans_id="", **kwargs):
        """
        支付查询
        :param org_req_date: 原始订单请求时间
        :param party_order_id: 微信支付宝的商户单号
        :param org_hf_seq_id: 交易返回的全局流水号
        :param out_trans_id: 微信支付宝的订单号
        :param org_req_seq_id: 原始请求流水号
        :param kwargs: 额外参数
        :return: 支付对象
        """

        required_params = {
            "org_req_date": org_req_date,
            "org_req_seq_id": org_req_seq_id,
            "org_hf_seq_id": org_hf_seq_id,
            "party_order_id": party_order_id,
            "out_trans_id": out_trans_id,
        }

        required_params.update(kwargs)
        return request_post_without_seq_id(online_payment_query, required_params)

    @classmethod
    def refund(cls, ord_amt, org_req_date, *, org_req_seq_id="", org_hf_seq_id="", org_party_order_id="", **kwargs):
        """
        发起退款
        :param ord_amt: 退款金额
        :param org_req_seq_id: 原始请求流水号
        :param org_req_date: 原始订单请求时间
        :param org_party_order_id: 微信支付宝的商户单号
        :param org_hf_seq_id: 交易返回的全局流水号
        :param kwargs: 额外参数
        :return: 返回报文
        """

        required_params = {
            "ord_amt": ord_amt,
            "org_req_date": org_req_date,
            "org_req_seq_id": org_req_seq_id,
            "org_hf_seq_id": org_hf_seq_id,
            "org_party_order_id": org_party_order_id,
        }

        required_params.update(kwargs)

        return request_post(online_payment_refund, required_params)

    @classmethod
    def query_refund(cls, org_req_date, *, org_req_seq_id="", org_hf_seq_id="", **kwargs):
        """
        退款查询
        :param org_req_seq_id: 原始请求流水号
        :param org_req_date: 原始退款请求时间
        :param org_hf_seq_id: 交易返回的全局流水号
        :param kwargs: 额外参数
        :return: 退款对象
        """
        required_params = {
            "org_req_date": org_req_date,
            "org_req_seq_id": org_req_seq_id,
            "org_hf_seq_id": org_hf_seq_id,
        }
        required_params.update(kwargs)
        return request_post_without_seq_id(online_payment_refund_query, required_params)

    @classmethod
    def close(cls, org_req_date, *, org_req_seq_id="", org_hf_seq_id="", **kwargs):
        """
        关单请求
        :param org_req_seq_id: 原始订单请求流水号
        :param org_req_date: 原始订单请求日期
        :param org_hf_seq_id: 交易返回的全局流水号
        :param kwargs: 额外参数
        :return: 关单对象
        """
        required_params = {
            "org_hf_seq_id": org_hf_seq_id,
            "org_req_date": org_req_date,
            "org_req_seq_id": org_req_seq_id
        }

        required_params.update(kwargs)
        return request_post(online_payment_close, required_params)

    @classmethod
    def query_close(cls, org_req_date, *, org_req_seq_id="", org_hf_seq_id="", **kwargs):
        """
        关单查询请求
        :param org_req_seq_id: 原始订单请求流水号
        :param org_req_date: 原始订单请求日期
        :param org_hf_seq_id: 交易返回的全局流水号
        :param kwargs: 额外参数
        :return: 关单对象
        """
        required_params = {
            "org_hf_seq_id": org_hf_seq_id,
            "org_req_date": org_req_date,
            "org_req_seq_id": org_req_seq_id
        }

        required_params.update(kwargs)
        return request_post(online_payment_close_query, required_params)
