<?php

namespace App\Facades\Wo;

use App\Facades\Wo\Log as LogFacade;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

/**
 * 花呗分期业务
 */
class Wo
{
    protected $baseUri;

    public function __construct()
    {
        $config = config('wo');

        $this->merchantCert = $config['merchantCert'];
        $this->merchant_id  = $config['merchant_id'];
        $this->charset      = $config['charset'];
        $this->version      = $config['version'];
        $this->signType     = $config['signType'];
        $this->channelType  = $config['channelType'];
        $this->baseUri      = $config['baseUri'];
    }

    //获取私钥
    public function getPrivate()
    {
        $config = config('wo');
        return file_get_contents($config['private']);
    }

    //获取公钥
    public function getPublic()
    {
        $config = config('wo');
        return file_get_contents($config['public']);
    }

    /**
     * 获取毫秒级别的时间戳
     */
    public function getMsecTime()
    {
        list($msec, $sec) = explode(' ', microtime());
        $msectime         = (float) sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
        $msectime         = explode('.', $msectime);

        return $msectime[0];
    }

    //签名
    public function rsaSign($params)
    {
        $signStr     = $this->getSignString($params);
        $private_key = $this->getPrivate();
        $privKeyId   = openssl_pkey_get_private($private_key);
        if (!$privKeyId) {
            return ['msg' => '私钥格式有误'];
        }
        $signature = '';
        openssl_sign($signStr, $signature, $privKeyId, OPENSSL_ALGO_SHA1);
        openssl_free_key($privKeyId);

        return bin2hex($signature);
    }

    /**
     * RSA验签
     * @param $params 待签名数据
     * @param $public_key 公钥字符串
     * @param $sign 要校对的的签名结果
     * return 验证结果
     */
    public function rsaCheck($params, $sign)
    {
        $public_key = $this->getPublic();
        $res        = openssl_get_publickey($public_key);
        $signStr    = $this->getSignString($params);

        if ($res) {
            $result = (bool) openssl_verify($signStr, $sign, $res);
            openssl_free_key($res);
        } else {
            return '公钥格式有误!';
        }

        return $result;
    }

    /**
     * 获取待签名字符串
     * @param    array     $params 参数数组
     * @return   string
     */
    public function getSignString($params)
    {
        $params = array_filter($params);
        ksort($params);
        $signStr = http_build_query($params);
        return $signStr;
    }

    //获取证书
    public function merchantCert()
    {
        if (!file_exists($this->merchantCert)) {
            return false;
        }
        $cert    = file_get_contents($this->merchantCert);
        $cer_key = bin2hex($cert);
        return $cer_key;
    }

    /**
     * 通用获取数据接口
     * @param  [type] $url    请求地址
     * @param  array  $query  传递参数
     * @param  array  $json   需要传的json数据
     * @param  string $method 方式
     * @return [type]         [description]
     */
    public function getWoData($params = [], $method = 'POST')
    {
        $url      = $this->baseUri;
        $postData = [
            'form_params' => $params,
        ];

        $log = LogFacade::insert($url, $method, $postData, 'wo'); //日志

        try {
            $client   = new Client();
            $response = $client->request($method, $url, $postData);
            $body     = $response->getBody();
            $content  = $body->getContents();
            $result   = json_decode($content, true);

            if (is_array($result)) {
                return '发券失败';
                LogFacade::update($log, $result); //更新日志
            }

            parse_str($content, $res);

            LogFacade::update($log, $res); //更新日志

            return $res;
        } catch (RequestException $e) {
            LogFacade::update($log, [$e->getMessage()]); //更新日志
            return ['ret' => '99999', $e->getMessage()];
        }
    }

}
