<?php

namespace App\Managers;

use App\Generated\Exceptions\CustomErrorMessageException;
use App\Jobs\OrderCloseJob;
use App\Models\CouponModel;
use App\Models\Fpdx\PairModel;
use App\Models\OrderModel;
use GuzzleHttp\Client;

class OrderManager
{

    protected $orderModel;
    protected $couponModel;
    protected $httpClient;

    public function __construct()
    {
        $this->httpClient = new Client();
        $this->orderModel = new OrderModel();
        $this->couponModel = new CouponModel();
    }


    /**
     * 72小时付费报名
     * @param  $uid
     * @param  array  $attach
     * @param  int  $couponId
     * @return int
     * @throws CustomErrorMessageException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function unifyOrderByPair($uid, array $attach, $couponId = 0)
    {
        $goodsId = 3;
        $goods = $this->orderModel::GOODS[$goodsId];
        $totalFee = $goods['total_fee'];

        // 计算优惠券
        if ($couponId) {
            $coupon = $this->couponModel->find($couponId);
            $settlement_amount = $coupon->getSettlementAmount($goodsId);
            $totalFee = $settlement_amount['settlement_total_amount'];
        }

        $attribute = [
            'uid' => $uid,
            'body' => "72小时恋爱体验报名",
            'total_fee' => $totalFee,
            'notify_url' => config('api.msy_url') . "/api/core/pay/notify/fpdx",
            'attach' => json_encode($attach)
        ];

        $prepayId = $this->unify($attribute);

        $order = $this->orderModel->create([
            'uid' => $uid,
            'out_trade_no' => $prepayId,
            'type' => $goodsId,
            'total_amount' => $goods['total_fee'],
            'total_fee' => $totalFee,
            'attach_data' => json_encode($attach),
            'coupon_id' => $couponId,
        ]);

        // 使用
        if ($couponId) {
            $coupon->use($goodsId, $order->id);
        }

        OrderCloseJob::dispatch($order->id)->onQueue('{order:close}')->delay(now()->addMinute(5));
        if ($totalFee == 0) {
            $params = [
                'out_trade_no' => $prepayId,
            ];
            $uri = config('api.pay_url') . "/payments/notify/koudai";
            $this->httpClient->request("POST", $uri, [
                'form_params' => $params
            ]);
            return 0;
        }
        return $order->id;
    }


    /**
     * 匹配补缴下单
     * @param  PairModel  $pair
     * @return OrderModel|\Illuminate\Database\Eloquent\Model
     * @throws CustomErrorMessageException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function unifyOrderByScore(PairModel $pair)
    {
        $goods = $this->orderModel::GOODS[3];
        $totalFee = $goods['total_fee'] - $pair->score;
        $attach = ['pair_id' => $pair->id,'uid' => $pair->uid, 'state' => 103];
        $attribute = [
            'uid' => $pair->uid,
            'body' => "72小时恋爱体验报名",
            'total_fee' => $totalFee,
            'notify_url' => config('api.msy_url') . "/api/core/pay/notify/fpdx",
            'attach' => json_encode($attach)
        ];
        $prepayId = $this->unify($attribute);

        $order = $this->orderModel->create([
            'uid' => $pair->uid,
            'out_trade_no' => $prepayId,
            'type' => $goods['goods_id'],
            'total_amount' => $totalFee,
            'total_fee' => $totalFee,
            'attach_data' => json_encode($attach)
        ]);

        return $order;
    }


    /**
     * 下单
     * @param  array  $attribute
     * @return mixed
     * @throws CustomErrorMessageException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    private function unify(array $attribute)
    {
        $uri = config('api.pay_url') . "/payments/unify";
        $client = $this->httpClient->request("POST", $uri, [
            'json' => $attribute
        ]);
        $response = json_decode($client->getBody()->getContents(), true);
        if (!isset($response['code']) || $response['code'] != 200) {
            throw new CustomErrorMessageException($response->message ?? "发起支付失败");
        }
        return $response['data']['order_id'];
    }
}
