<?php

namespace Modules\Base\Entities;

use Illuminate\Database\Eloquent\Model;

class UserWallet extends Model
{
    const CHARGE = 1;
    const PAY_ORDER = 2;
    const WITHDRAWAL = 3;
    const ORDER_REWARD = 4;
    const ADMIN_ADD = 5;
    const WITHDRAWAL_FAIL_BACK = 6;

    protected $primaryKey = 'user_id';
    public $incrementing = false;
    protected $fillable = ['money', 'user_id', 'pay_password'];

    /**使用钱包金额
     * @param $value
     * @param $type
     * @param int $type_id
     * @param string $wallet_type
     * @return mixed
     * @throws \Exception
     */
    public function useWallet($value, $type, $type_id = 0, $wallet_type = 'money')
    {
        return $this->changeWalllet(-$value, $type, $type_id, $wallet_type);
    }

    /**
     * 增加钱包金额
     *
     * @param $value
     * @param $type
     * @param int    $type_id
     * @param string $wallet_type
     *
     * @throws \Exception
     *
     * @return mixed
     */
    public function addWallet($value, $type, $type_id = 0, $wallet_type = 'money')
    {
        return $this->changeWalllet($value, $type, $type_id, $wallet_type);
    }

    /**
     * 改变钱包金额
     *
     * @param $value
     * @param $type
     * @param int    $type_id
     * @param string $wallet_type
     *
     * @throws \Exception
     *
     * @return mixed
     */
    public function changeWalllet($value, $type, $type_id = 0, $wallet_type = 'money')
    {
        $this->exists || $this->save();

        if ($value < 0 && $this->$wallet_type < -$value) {
            throw new \Exception('余额不足');
        }

        $type_id = ($type_id == 0 && $type == self::ADMIN_ADD) ? self::getAdminAddId() : $type_id;

        $result = $this->log()->create(compact('value', 'type', 'type_id', 'wallet_type'));

        if ($result) {
            return self::get($this->user_id);
        }

        throw new \Exception('未知错误');
    }

    /**
     * 日志关联关系
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function log()
    {
        return $this->hasMany(UserWalletLog::class, 'user_id');
    }

    /**
     * 获取钱包实例
     *
     * @param null $user_id
     *
     * @return mixed
     */
    public static function get($user_id = null)
    {
        if ($user_id == null) {
            $user_id = \Auth::id();
        }

        abort_unless($user_id, 401);

        $wallet = static::firstOrCreate(['user_id' => $user_id]);

        return $wallet;
    }

    /**
     * @param null   $type_id
     * @param string $wallet_type
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function walletLog($type = null, $wallet_type = 'money')
    {
        $query = $this->log()->where('wallet_type', $wallet_type);
        $query->when($type, function ($query, $type) {
            $query->where('type', $type);
        });

        return $query->orderByDesc('id');
    }

    /**
     * @return int
     */
    public static function getAdminAddId()
    {
        return UserWalletLog::where('wallet_type', 'money')->where('type', self::ADMIN_ADD)->max('type_id') + 1;
    }

}
