<?php

namespace App\libs\wechat\wxpay;

use lc\wechat\wxpay\base\WxPayHelper;
use lc\wechat\wxpay\base\WxPayException;
use lc\wechat\wxpay\base\WxPayConfig;
use Illuminate\Support\Facades\Config;

/**
 * 微信支付类
 * 接口访问类，包含所有微信支付API列表的封装，类中方法为static方法，
 * 每个接口有默认超时时间（除提交被扫支付为10s，上报超时时间为1s外，其他均为6s）.
 */
class WxPayApi
{
    /**
     * 企业付款到零钱(用于企业向微信用户个人付款).
     *
     * @param array $params 接口请求参数
     *
     * @return  array
     *
     * @throws base\WxPayException
     */
    public static function payToBalance(array $params)
    {
        $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';

        new WxPayConfig();
        $base = [
            'mch_appid'        => Config::get('lc.wxpay.appid', WxPayConfig::$appId),
            'mchid'            => WxPayConfig::$mchId,
            'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],
            'nonce_str'        => uniqid(),
        ];
        $params = array_merge($base, $params);

        return WxPayHelper::sendRedPackRequest(1, $url, array_merge($base, $params));
    }

    /**
     * 查询企业付款到零钱(用于企业向微信用户个人付款).
     *
     * @param array $params 接口请求参数
     *
     * @return  array
     *
     * @throws base\WxPayException
     */
    public static function queryBalance(array $params)
    {
        $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo';

        new WxPayConfig();
        $base = [
            'appid'     => Config::get('lc.wxpay.appid', WxPayConfig::$appId),
            'mch_id'    => WxPayConfig::$mchId,
            'nonce_str' => uniqid(),
        ];
        $params = array_merge($base, $params);

        return WxPayHelper::queryRequest(1, $url, array_merge($base, $params));
    }

    /**
     * 查询现金红包红包记录.
     *
     * @param array $params 接口请求参数
     *
     * @return  array
     *
     * @throws base\WxPayException
     */
    public static function queryRedPack(array $params)
    {
        $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo';

        new WxPayConfig();
        $base = [
            'appid'     => Config::get('lc.wxpay.appid', WxPayConfig::$appId),
            'mch_id'    => WxPayConfig::$mchId,
            'nonce_str' => uniqid(),
            'bill_type' => 'MCHT',
        ];
        $params = array_merge($base, $params);

        return WxPayHelper::queryRequest(2, $url, array_merge($base, $params));
    }

    /**
     * 发放现金红包.
     *
     * @param array $params 接口请求参数
     *
     * @return  array
     *
     * @throws WxPayException
     */
    public static function sendRedPack(array $params)
    {
        $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack';

        new WxPayConfig();
        $base = [
            'wxappid'   => Config::get('lc.wxpay.appid', WxPayConfig::$appId),
            'mch_id'    => WxPayConfig::$mchId,
            'client_ip' => $_SERVER['REMOTE_ADDR'],
            'nonce_str' => uniqid(),
        ];
        $params = array_merge($base, $params);

        return WxPayHelper::sendRedPackRequest(2, $url, array_merge($base, $params));
    }

    /**
     * 微信支付统一下单.
     *
     * @param array $params 接口请求参数
     *
     * @return  array
     *
     * @throws WxPayException
     */
    public static function unifiedOrder(array $params)
    {
        $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';

        new WxPayConfig();
        $base = [
            'appid'            => Config::get('lc.wxpay.appid', WxPayConfig::$appId),
            'mch_id'           => WxPayConfig::$mchId,
            'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],
            'nonce_str'        => uniqid(),
        ];

        return WxPayHelper::sendUnifyRequest($url, array_merge($base, $params), 'unifiedOrder');
    }

    /**
     * 查询订单.
     *
     * @param string $transactionId 微信订单号
     *
     * @return  array
     *
     * @throws WxPayException
     */
    public static function queryByTransactionId(string $transactionId)
    {
        return self::queryOrder(['transaction_id' => $transactionId]);
    }

    /**
     * 查询订单.
     *
     * @param string $outTradeNo 商户订单号
     *
     * @return  array
     *
     * @throws WxPayException
     */
    public static function queryByOutTradeNumber(string $outTradeNo)
    {
        return self::queryOrder(['out_trade_no' => $outTradeNo]);
    }

    /**
     * 申请退款.
     *
     * @param string $transactionId 微信订单号
     * @param array  $params        接口请求参数
     *
     * @return  array
     *
     * @throws WxPayException
     */
    public static function refundByTransactionId(string $transactionId, array $params)
    {
        return self::refund(array_merge(['transaction_id' => $transactionId], $params));
    }

    /**
     * 申请退款.
     *
     * @param string $outTradeNo 微信订单号
     * @param array  $params     接口请求参数
     *
     * @return  array
     *
     * @throws WxPayException
     */
    public static function refundByOutTradeNumber(string $outTradeNo, array $params)
    {
        return self::refund(array_merge(['out_trade_no' => $outTradeNo], $params));
    }

    /**
     * 微信订单号退款查询.
     *
     * @param string $transactionId 微信订单号
     *
     * @return  array
     *
     * @throws WxPayException
     */
    public static function queryRefundByTransactionId(string $transactionId)
    {
        return self::refundQuery(['transaction_id' => $transactionId]);
    }

    /**
     * 商户订单号退款查询.
     *
     * @param string $outTradeNo 商户订单号
     *
     * @return  array
     *
     * @throws WxPayException
     */
    public static function queryRefundByOutTradeNumber(string $outTradeNo)
    {
        return self::refundQuery(['out_trade_no' => $outTradeNo]);
    }

    /**
     * 商户退款单号退款查询.
     *
     * @param string $outRefundNo 商户退款单号
     *
     * @return  array
     *
     * @throws WxPayException
     */
    public static function queryRefundByOutRefundNumber(string $outRefundNo)
    {
        return self::refundQuery(['out_refund_no' => $outRefundNo]);
    }

    /**
     * 微信退款单号退款查询.
     *
     * @return  array
     *
     * @throws WxPayException
     */
    public static function queryRefundByRefundId(string $refundId)
    {
        return self::refundQuery(['refund_id' => $refundId]);
    }

    /**
     * 微信支付订单查询.
     *
     * @param array $params 接口请求参数
     *
     * @return  array
     *
     * @throws WxPayException
     */
    private static function queryOrder(array $params)
    {
        $url = 'https://api.mch.weixin.qq.com/pay/orderquery';

        new WxPayConfig();
        $base = [
            'appid'     => Config::get('lc.wxpay.appid', WxPayConfig::$appId),
            'mch_id'    => WxPayConfig::$mchId,
            'nonce_str' => uniqid(),
        ];

        return WxPayHelper::sendUnifyRequest($url, array_merge($base, $params), 'queryOrder');
    }

    /**
     * 微信支付关闭订单.
     *
     * @param string $outTradeNo 订单号
     *
     * @return  array
     *
     * @throws WxPayException
     */
    public static function closeOrder(string $outTradeNo)
    {
        $url = 'https://api.mch.weixin.qq.com/pay/closeorder';

        new WxPayConfig();
        $params = [
            'appid'        => Config::get('lc.wxpay.appid', WxPayConfig::$appId),
            'mch_id'       => WxPayConfig::$mchId,
            'nonce_str'    => uniqid(),
            'out_trade_no' => $outTradeNo,
        ];

        return WxPayHelper::sendUnifyRequest($url, $params, 'closeOrder');
    }

    /**
     * 微信支付申请退款.
     *
     * @param array $params 接口请求参数
     *
     * @return  array
     *
     * @throws WxPayException
     */
    private static function refund(array $params)
    {
        $url = 'https://api.mch.weixin.qq.com/secapi/pay/refund';

        new WxPayConfig();
        $base = [
            'appid'     => Config::get('lc.wxpay.appid', WxPayConfig::$appId),
            'mch_id'    => WxPayConfig::$mchId,
            'nonce_str' => uniqid(),
        ];
        $params = array_merge($base, $params);

        return WxPayHelper::sendUnifyRequest($url, $params, 'refund');
    }

    /**
     * 微信支付退款查询.
     *
     * @param array $params 接口请求参数
     *
     * @return  array
     *
     * @throws WxPayException
     */
    private static function refundQuery(array $params)
    {
        $url = 'https://api.mch.weixin.qq.com/pay/refundquery';

        new WxPayConfig();
        $base = [
            'appid'     => Config::get('lc.wxpay.appid', WxPayConfig::$appId),
            'mch_id'    => WxPayConfig::$mchId,
            'nonce_str' => uniqid(),
        ];
        $params = array_merge($base, $params);

        return WxPayHelper::sendUnifyRequest($url, $params, 'refundQuery');
    }

    /**
     * 微信发送商家优惠券.
     *
     * @return array
     */
    public static function unifiedOrderForCoupon(array $params)
    {
        $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/send_coupon';
        new WxPayConfig();
        $base = [
            'appid'     => Config::get('lc.wxpay.appid', WxPayConfig::$appId),
            'mch_id'    => WxPayConfig::$mchId,
            'nonce_str' => uniqid(),
        ];

        return WxPayHelper::sendUnifyRequest($url, array_merge($base, $params), 'send_coupon');
    }

    /**
     * 企业微信发送红包（付款到零钱）.
     *
     * @return array
     */
    public static function qywxSendBalance(array $params)
    {
    }
}
