<?php

namespace App\Libs\Pay;

use GuzzleHttp\Client;
use Exception;
use Log;

class Palmpay  implements PayMerchantInterface {

    /**
     * @var mixed
     */
    private $appId = '6196';
    /**
     * @var mixed
     */
    private $mchId = '2132225001';
    /**
     * @var mixed
     */
    private $appkey = 'a17465d30ad74105a38948b8ce14237e';
    /**
     * @var mixed
     */
    private $subAppid;
    /**
     * @var Client
     */
    private $payClient;

    private $log;

    function __construct($config)
    {
        $this->subAppid = $config['subAppid'];
        $this->payClient = new client(['base_uri'=>'https://pay.palmpay.cn/','timeout'=>5]);
        $this->log = myLog('Palmpay');
    }

    //生成订单
    function send(array $data)
    {
        $data = [
            'mchId'=>$this->mchId,
            'appid'=>$this->appId,
            'version'=>'3.0',
            'productName'=>$data['body'],
            'productDesc'=>$data['body'],
            'openid'=>$data['openid'],
            'subAppid'=>$this->subAppid,
            'ip' => $data['create_ip'],
            'money'=>$data['price'],
            'outTradeNo'=>$data['trade_no'],
            'notifyUrl'=>$data['notify_url']
        ];
        $data['sign'] = $this->makeSign($data);
        $pay_url = "sdkServer/thirdpays/pay/WECHAT_MNPROGRAM?".http_build_query($data);
        $response = '';
        try{
            $response = $this->payClient->request('GET',$pay_url)->getBody()->getContents();
            $response_object = json_decode($response,1);
            if(!$response_object['errcode']){
                $this->log->info('pay-result',$response_object['result']);
                return $response_object['result'];
            }

            $this->log->error('palmpay-error',[
                'data'=>$data,
                'response'=>$response_object
            ]);
            return [];
        }catch (Exception $e)
        {
            $this->log->error('palmpay-exception',[
                'msg'=>$e->getMessage(),
                'data'=>$data
            ]);
        }
        return [];
    }

    function makeSign(array $params)
    {
        return md5($params['appid'].'WECHAT_MNPROGRAM'.$params['money'].($params['outTradeNo'] ??"").$this->appkey);
    }



    /**
     * 支付回调
     * @param array $data
     */
    public function notify(array $data)
    {
        $this->log->info('pay-notify',$data);
        $sign = $data['sign'];
        $my_sign = $this->signCheck($data,$this->appkey);
        $this->log->info('pay-notify',[
            'sign'=>$sign,
            'my_sign'
        ]);
        return $sign == $my_sign;
    }

    /**
     * 订单查询
     * @param string $trade_no 商户订单号
     * @return bool
     */
    public function query(string $trade_no)
    {

    }

    /**
     * 退款申请
     * @param array $data
     * $data = [
     *  'third_orderid' => "", // 商户订单号
     * 'price' =>  "", // 总金额，以元为单位
     * 'refund_no' =>  '' , // 商户系统内部的退款单号，确保在商户系统下唯一，只能是数字、大小写字母_-|*@ ，同一退款单号多次请求只退一笔。
     * 'refund_price' =》 '', //退款总金额,单位为元，可部分退款
     * 'remark' =>  '' // 备注
     * ]
     */
    public function refund( $data)
    {
        $data = [
            'mchId'=>$this->mchId,
            'appid'=>$this->appId,
            'version'=>'3.0',
            'pdorderid' => $data['third_orderid'],
            'money' =>  bcmul($data['price'] ,100,0),
            'outRefundNo' => $data['refund_no'],
            'refundMoney' => bcmul($data['refund_price'],100,0) ,
            "refundReason" => $data['remark'] ?? "用户要求退款",
        ];
        $data['sign'] = $this->makeRefundSign($data);
        $pay_url = "sdkServer/thirdpays/refund?".http_build_query($data);
        $response = '';
        try{
            $response = $this->payClient->request('GET',$pay_url)->getBody()->getContents();
            $response_object = json_decode($response,1);

            if(!$response_object['resultCode']){
                $this->log->info('refund-result',$response_object['result']);
                return ['status' => 1,"退款成功"];
            }

            $this->log->error('refund-error',[
                'data'=>$data,
                'response'=>$response_object
            ]);
            return ['status' => 0,'msg' => $response_object['message'] ??"接口退款失败" ];
        }catch (Exception $e)
        {
            $this->log->error('refund-exception',[
                'msg'=>$e->getMessage(),
                'data'=>$data
            ]);
        }
        return ['status' => 0,'msg' => "退款失败"];
    }



    private function signCheck($params, $key) {
        $signPars = "";
        ksort($params);
        foreach($params as $k => $v) {
            if("" != $v && "sign" != $k) {
                $signPars .= $k . "=" . $v . "&";
            }
        }
        $signPars .= "key=".$key;
        return md5($signPars);
    }

    private function makeRefundSign(array $data)
    {
       return md5($data['mchId'].$data['appid'].$data['pdorderid'].$data['money'].$data['version'].$data['outRefundNo'].$data['refundMoney'].$this->appkey);
    }
}
