<?php

namespace Modules\Payment\Traits;

use Exception;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\Relations\MorphOne;
use Modules\Payment\Models\Payment;
use Modules\User\Models\User;

trait WithPayments
{

    /**
     * Notes   : 自动获取订单的应付金额
     *           主模型应设置  protected $amount_field = 'xxx';
     *
     * @Date   : 2021/4/23 10:32 上午
     * @Author : < Jason.C >
     * @throws \Exception
     */
    protected function getTotalPayAmount()
    {
        if (! in_array('amount_field', array_keys(get_class_vars(__CLASS__))) || empty($this->amount_field)) {
            throw new Exception('Model need [amount_field] property');
        }

        return $this->getOriginal($this->amount_field);
    }

    /**
     * Notes   : 关联支付订单
     *
     * @Date   : 2021/4/21 1:49 下午
     * @Author : < Jason.C >
     * @return \Illuminate\Database\Eloquent\Relations\MorphMany
     */
    public function payments(): MorphMany
    {
        return $this->morphMany(Payment::class, 'order');
    }

    /**
     * Notes: 关联支付信息
     *
     * @Author: 玄尘
     * @Date  : 2021/5/17 9:26
     * @return \Illuminate\Database\Eloquent\Relations\MorphOne
     */
    public function payment(): MorphOne
    {
        return $this->morphOne(Payment::class, 'order')->where('state', Payment::STATUS_SUCCESS);
    }

    /**
     * Notes: 是否支付
     *
     * @Author: 玄尘
     * @Date  : 2021/5/17 9:04
     */
    public function isPay(): bool
    {
        return $this->payments()->where('state', Payment::STATUS_SUCCESS)->exists();
    }

    /**
     * Notes   : 创建微信支付订单
     *
     * @Date   : 2021/4/21 1:55 下午
     * @Author : < Jason.C >
     * @param  \Modules\User\Models\User  $user  下单用户
     * @param  float  $total  订单金额
     * @param  string  $gateway  支付渠道
     * @return \Illuminate\Database\Eloquent\Model
     * @throws \Exception
     */
    public function createWechatPayment(User $user, float $total = -1, string $gateway = 'mp'): Model
    {
        $gatewayAll = ['mp', 'wap', 'app', 'miniapp', 'scan'];
        if (config('payment.version', 2) == 3) {
            $gatewayAll = ['mp', 'wap', 'app', 'mini', 'scan'];
            if ($gateway == 'miniapp') {
                $gateway = 'mini';
            }
        }

        if (! in_array($gateway, $gatewayAll)) {
            throw new Exception('Unsupported Wechat gateway');
        }

        // 自动获取订单金额
        if ($total < 0) {
            $total = $this->getTotalPayAmount();
        }

        return $this->payments()->create([
            'user'    => $user,
            'total'   => $total,
            'driver'  => Payment::DRIVER_WECHAT,
            'gateway' => $gateway,
        ]);
    }

    /**
     * Notes   : 创建支付宝订单
     *
     * @Date   : 2021/4/23 10:24 上午
     * @Author : < Jason.C >
     * @param  \Modules\User\Models\User  $user  下单用户
     * @param  float  $total  订单金额
     * @param  string  $gateway  支付渠道
     * @return \Illuminate\Database\Eloquent\Model
     * @throws \Exception
     */
    public function createAlipayPayment(User $user, float $total = -1, string $gateway = 'web'): Model
    {
        if (! in_array($gateway, ['web', 'wap', 'app', 'mini', 'scan'])) {
            throw new Exception('Unsupported Alipay gateway');
        }
        // 自动获取订单金额
        if ($total < 0) {
            $total = $this->getTotalPayAmount();
        }

        return $this->payments()->create([
            'user'    => $user,
            'total'   => $total,
            'driver'  => Payment::DRIVER_ALIPAY,
            'gateway' => $gateway,
        ]);
    }

    /**
     * Notes: 水滴支付
     *
     * @Author: 玄尘
     * @Date: 2022/9/5 15:50
     * @param  User  $user
     * @param  float  $total
     * @param  string  $gateway
     * @return Model
     * @throws Exception
     */
    public function createScorePayment(User $user, float $total = -1, string $gateway = 'web'): Model
    {
        // 自动获取订单金额
        if ($total < 0) {
            $total = $this->getTotalPayAmount();
        }

        return $this->payments()->create([
            'user'    => $user,
            'total'   => $total,
            'driver'  => Payment::DRIVER_SCORE,
            'gateway' => $gateway,
        ]);
    }

}