<?php

namespace Server\payment\run;

use App\Http\Middleware\AppRuntime;
use Illuminate\Support\Facades\Log;
use Server\payment\lib\AesUtil;
use Server\payment\PaymentService;

class IndexController extends PaymentService {

    public function initAccount($uniacid){
        $_GET['i'] = $uniacid;
        (new AppRuntime())->Runtime($uniacid);
        parent::__construct($uniacid);
    }

    /**
     * @throws \Exception
     */
    public function decryptToString($data){
        if (empty($data)) return error(-1, "解析失败");
        if (empty($this->configs['wechat']['apikey'])) return error(-1, "未配置支付秘钥");
        if (!class_exists('Server\payment\lib\AesUtil')){
            if(!file_exists(base_path("/servers/payment/lib/AesUtil.php"))){
                throw new \Exception("Util file 'AesUtil' dose not exists.");
            }
            include_once base_path("/servers/payment/lib/AesUtil.php");
        }
        try {
            $AesUtil = new AesUtil($this->configs['wechat']['apikey']);
            $response = $AesUtil->decryptToString($data['resource']['associated_data'], $data['resource']['nonce'], $data['resource']['ciphertext']);
            if(empty($response)) return error(-1, "解析失败");
            if (is_error($response)) return $response;
            return json_decode($response, true);
        }catch (\Exception $exception){
            return error(-1, $exception->getMessage());
        }
    }

    public function doRefund($uniacid){
        if (empty($uniacid)) abort(404,'找不到该平台');
        $this->initAccount($uniacid);
        $data = request()->all();
        $return = array("code"=>"ERROR", "message"=>"失败");
        $result = $this->decryptToString($data);
        if (is_error($result)){
            $return['message'] = $result['message'];
        }else{
            if ($result['refund_status']=='SUCCESS'){
                $params = [
                    'out_trade_no'=>$result['out_trade_no'],
                    'tid'=>$result['out_refund_no'],
                    'refund_id'=>$result['refund_id'],
                    'mchid'=>$result['mchid'],
                    'transaction_id'=>$result['transaction_id']
                ];
                $return = array("code"=>"SUCCESS", "message"=>"成功", "result"=>$this->refundResult($params));
            }
        }
        return response()->json($return);
    }

    function __call($name, $arguments){
        if (strexists($name, 'refund')){
            $uniacid = intval(str_replace("refund", "", $name));
            return $this->doRefund($uniacid);
        }
        $uniacid = intval(str_replace("notify", "", $name));
        if (empty($uniacid)) abort(404,'找不到该平台');
        $inputs = request()->all();
        $this->initAccount($uniacid);
        $return = array("code"=>"ERROR", "message"=>"失败");
        if (!empty($inputs['resource'])){
            $data = $inputs;
        }else{
            $input = file_get_contents('php://input');
            $data = !empty($input) ? json_decode($input, true) : [];
        }
        try {
            $result = $this->decryptToString($data);
            if (!is_error($result)){
                if (isset($result['out_trade_no']) && $result['trade_state']=="SUCCESS"){
                    $payResult = $this->Notify("wechat", array(
                        "out_trade_no"=>$result['out_trade_no']
                    ));
                    if (is_error($payResult)){
                        $return['message'] = $payResult['message'];;
                    }else{
                        $return = array("code"=>"SUCCESS", "message"=>"成功", "data"=>$payResult);
                    }
                }
            }else{
                $return['message'] = $result['message'];
            }
        } catch (\Exception $exception) {
            Log::error('Exception: '.$exception->getMessage(), [
                'trace' => $exception->getTraceAsString(),
                'file' => $exception->getFile(),
                'line' => $exception->getLine(),
                'request' => request()->all(), // 记录请求信息
            ]);
            $return['message'] = $exception->getMessage();
        }
        return response()->json($return);
    }

}
