<?php

namespace app\common\util;

use EasyWeChat\Factory;
use EasyWeChat\Kernel\Exceptions\DecryptException;
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use EasyWeChat\Kernel\Support\Collection;
use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\ResponseInterface;


class MiniProgram
{
//    public const pay_notify_url = 'https://natapp.sphper.com';
    public const pay_notify_url = 'https://test.server.ycxxkj.com/deliver/api/public/index.php';

    /**
     * 小程序实例
     * @return object
     */
    public static function getApp(): object
    {
        $wechat = config('wechat');
        $config = [
            // 必要配置
            'app_id' => $wechat['app_id'],//appId
            'secret' => $wechat['secret'],

            // 下面为可选项
            // 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
            'response_type' => 'array',
        ];
        return Factory::miniProgram($config);
    }

    /**
     * 支付实例
     * @return object
     */
    public static function getPay(): object
    {
        $wechat = config('wechat');
        $config = [
            // 必要配置
            'app_id' => $wechat['app_id'],
            'mch_id' => $wechat['mch_id'],
            'key' => $wechat['key'],
            'cert_path' => $wechat['cert_path'],
            'key_path' => $wechat['key_path'],
            'notify_url' => $wechat['notify_url'],
        ];
        return Factory::payment($config);
    }

    /**
     * 获取手机号 非解密
     * @param $code
     * @return array|Collection|object|ResponseInterface|string
     * @throws InvalidConfigException
     * @throws GuzzleException
     */
    public static function getPhoneNumber($code)
    {
        $params = [
            'code' => $code
        ];
        $app = self::getApp();
        return $app->live->httpPostJson('wxa/business/getuserphonenumber', $params);
    }

    /**
     * 获取手机号 解密
     * @param $session_key
     * @param $iv
     * @param $encryptedData
     * @return array
     * @throws DecryptException
     */
    public static function getPhoneNumberIv($session_key, $iv, $encryptedData): array
    {
        $app = self::getApp();
        return $app->encryptor->decryptData($session_key, $iv, $encryptedData);
    }

    /**
     * NATIVE
     * @param $order_no
     * @param $total_fee
     * @return false|string
     */
    public static function nativePay($order_no, $total_fee)
    {
        $app = self::getPay();
        $result = $app->order->unify([
            'trade_type' => 'NATIVE',
            'body' => '快递柜费用',
            'out_trade_no' => $order_no,
            'total_fee' => $total_fee * 100,
            'notify_url' => self::pay_notify_url . '/mobile/payNotify/index',
            'product_id' => 1, // $message['product_id'] 则为生成二维码时的产品 ID
            // ...
        ]);
        if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
            return QrCode::createEwm($result['code_url']);
        }
        return false;
    }

    /**
     * JSAPI
     * @param $order_no
     * @param $total_fee
     * @param $openid
     * @return mixed
     */
    public static function JsApiPay($order_no, $total_fee, $openid)
    {
        $app = self::getPay();
        $jsSdk = $app->jssdk;

        $result = $app->order->unify([
            'body' => '快递柜费用',
            'out_trade_no' => $order_no,
            'total_fee' => intval($total_fee * 100),
            'notify_url' => self::pay_notify_url . '/api/payNotify/index', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
            'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
            'openid' => $openid,
        ]);
        $pay_json = false;
        if ($result['return_code']=='SUCCESS'&&$result['result_code']=='SUCCESS'){
            $pay_json = json_decode($jsSdk->bridgeConfig($result['prepay_id']));
        }


        return $pay_json;
    }


    /**
     * 创建二维码
     * @param $param
     * @return string
     */
    public static function createEwm($param): string
    {
        $app = self::getApp();

        $response = $app->app_code->get(config('ewm.path') . '?' . $param);

        $file_name = self::rand() . '.png';
        $dir = public_path() . 'storage/topic/' . date('Ymd');
        if (!is_dir($dir)) {
            mkdir($dir);
        }
        $saveFile = $dir . '/' . $file_name;
        $url = request()->domain() . getVirRootDir() . '/storage/topic/' . date('Ymd') . '/' . $file_name;
        file_put_contents($saveFile, $response);
        return $url;
    }

    private static function rand()
    {
        $len = 10;
        $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
        $string = time();
        for (; $len >= 1; $len--) {
            $position = rand() % strlen($chars);
            $position2 = rand() % strlen($string);
            $string = substr_replace($string, substr($chars, $position, 1), $position2, 0);
        }
        return $string;

    }
}