<?php

namespace Modules\Project\Http\Controllers\Api;

use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Log;
use Modules\Base\Services\OpenloginService;
use Modules\Project\Entities\Order;
use Modules\Project\Entities\UserWallet;
use Modules\Project\Http\Requests\PaymentRequest;
use Modules\Project\Services\OrderService;
use Overtrue\LaravelWeChat\Facade as EasyWeChat;
use function EasyWeChat\Kernel\Support\generate_sign;

class PaymentController extends \Modules\Base\Http\Controllers\Api\ApiController
{
    /**
     * 支付
     *
     * @OA\POST(
     *     tags={"支付"},
     *     summary="小程序支付",
     *     path="/api/payment/mini",
     *     security={
     *         {"jwt_auth": {}}
     *     },
     *     @OA\Parameter(
     *         name="order_id",
     *         in="query",
     *         description="订单id 不是订单号",
     *         required=true,
     *         @OA\Schema(
     *             type="string"
     *         )
     *     ),
     *     @OA\Response(
     *          response="200",
     *          description="成功",
     *          @OA\MediaType(
     *             mediaType="application/json",
     *              @OA\Schema(
     *                  type="object",
     *                  @OA\Property(
     *                      property="data",
     *                      type="array",
     *                      @OA\Items(),
     *                      description="列表"
     *                  ),
     *              )
     *          )
     *      )
     * )
     */
    public function mini()
    {
        $openid = app(OpenloginService::class)->userOpenid($this->user);

        $order_id = Input::post('order_id');

        $order_info = (new Order())->findOrFail($order_id);

        $payment = EasyWeChat::payment();

        $result = $payment->order->unify([
            'body' => '订单支付',
            'out_trade_no' => $order_info->order_no,
            'trade_type' => 'JSAPI',  // 必须为JSAPI
            'openid' => $openid, // 这里的openid为付款人的openid
            'total_fee' => bcmul($order_info->payable_amount, 100, 0), // 总价
        ]);

        // 如果成功生成统一下单的订单，那么进行二次签名
        if ($result['return_code'] === 'SUCCESS') {
            // 二次签名的参数必须与下面相同
            $params = [
                'appId' => config('wechat.payment.default.app_id'),
                'timeStamp' => time().'',
                'nonceStr' => $result['nonce_str'],
                'package' => 'prepay_id='.$result['prepay_id'],
                'signType' => 'MD5',
            ];

            $params['paySign'] = generate_sign($params, config('wechat.payment.default.key'));

            return $this->response->array($params);
        } else {
            return $result;
        }
    }

    /**
     * 支付
     *
     * @OA\POST(
     *     tags={"支付"},
     *     summary="余额支付",
     *     path="/api/payment/balance",
     *     security={
     *         {"jwt_auth": {}}
     *     },
     *     @OA\Parameter(
     *         name="order_id",
     *         in="query",
     *         description="订单id 不是订单号",
     *         required=true,
     *         @OA\Schema(
     *             type="string"
     *         )
     *     ),
     *     @OA\Parameter(
     *         name="pay_password",
     *         in="query",
     *         description="支付密码",
     *         required=true,
     *         @OA\Schema(
     *             type="string"
     *         )
     *     ),
     *     @OA\Response(
     *          response="200",
     *          description="成功",
     *          @OA\MediaType(
     *             mediaType="application/json",
     *              @OA\Schema(
     *                  type="object",
     *                  @OA\Property(
     *                      property="data",
     *                      type="array",
     *                      @OA\Items(),
     *                      description="列表"
     *                  ),
     *              )
     *          )
     *      )
     * )
     */
    public function balance(PaymentRequest $request)
    {
        $user_id = \Auth()->id();

        $order_id = $request->get('order_id');

        $order_info = (new Order())->findOrFail($order_id);

        if ($order_info->status != Order::STATUS_DEFAULT) {
            throw \Illuminate\Validation\ValidationException::withMessages([
                'order_id' => ['订单当前状态不可支付。'],
            ]);
        }

        $pay_money = $order_info->payable_amount;

        $user_walle = UserWallet::get($user_id);

        if ($user_walle->money >= $pay_money) {
            $user_walle->useWallet($pay_money, UserWallet::PAY_ORDER, $order_id);

            $order_service = new OrderService($order_info);

            $order_service->paymentSuccess([

                'paid_amount' => $pay_money,

                'type' => 'balance',

            ]);
        } else {
            throw new \Exception('余额不足');
        }

        return $this->response->noContent()->setStatusCode(204);
    }

    public function notify()
    {
        $payment = EasyWeChat::payment();

        $response = $payment->handlePaidNotify(function ($message, $fail) {
            Log::debug('pay notify');
            Log::debug(var_export($message, 1));

            $order = Order::where('order_no', $message['out_trade_no'])->get()->first();

            //没有找到 或者 状态为已支付 直接略过
            if (!$order || $order->status >= Order::STATUS_PAID) {
                return true;
            }

            if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态，不代表支付状态
                // 用户是否支付成功
                if (array_get($message, 'result_code') === 'SUCCESS') {
                    $order_service = new OrderService($order);

                    $data = [
                        'paid_amount' => bcdiv($message['total_fee'], 100, 2),
                    ];

                    $order_service->paymentSuccess($data);

                    return true;

                // 用户支付失败
                } elseif (array_get($message, 'result_code') === 'FAIL') {

                    //既然失败了 ，那就不处理
                    return true;
                    //$order->status = 'paid_fail';
                }
            } else {
                return $fail('通信失败，请稍后再通知我');
            }

            return true;
        });

        return $response;
    }
}
