<?php
/**
+-----------------------------------------------------------------------------------------------------------------------
 * 模型层:用户 模型类
+-----------------------------------------------------------------------------------------------------------------------
 *
 * PHP version 7
 *
 * @category  App\Models\User
 * @package   App\Models\User
 * @author    Richer <yangzi1028@163.com>
 * @date      2020年12月28日09:25:20
 * @copyright 2020-2022 Richer (http://www.Richer.com/)
 * @license   http://www.Richer.com/ License
 * @link      http://www.Richer.com/
 */
namespace App\Models\User;

use App\Models\Traits\CanFavorite;
use App\Models\Traits\UserTrait;
use App\Models\Traits\UserWalletTrait;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;
use Tymon\JWTAuth\Contracts\JWTSubject;

/**
 * @property mixed id
 * @property mixed sort
 * @property mixed status
 * @property mixed status_show
 * @property mixed created_at
 * @property mixed updated_at
 * @property mixed inviter_id
 * @property mixed|null points
 * @property mixed|string password
 * @property mixed|string invite_code
 * @property int|mixed balance
 * @property mixed username
 * @property mixed name
 * @property mixed nickname
 * @property mixed avatar
 * @property mixed mobile
 * @property mixed gender
 * @property mixed gender_show
 * @property mixed registered_at
 * @property mixed favorites
 * @property mixed carts
 * @property mixed role_show
 * @property mixed role
 * @property mixed house_number
 * @property mixed address
 * @property int|mixed pid
 * @property int|mixed gid
 * @property mixed openid
 * @property mixed registered_ip
 * @property int|mixed times
 */
class User extends Authenticatable implements JWTSubject
{
    use UserTrait, CanFavorite, UserWalletTrait;

    // 指定数据库表
    const TABLE = 'users';
    protected $table = self::TABLE;

    // 指定对象显示名称:方便系统统一查询和做其他处理
    const OBJ_NAME      = 'user';
    const OBJ_NAME_ZH   = '普通用户';

    // 用于laravel-admin switch 控件

    /**
     * 用户性别业务常量配置
     */
    const UNKNOWN = 0;// 有效
    const MALE    = 1;// 有效
    const FEMALE  = 2;// 禁用

    const GENDER_OPTIONS = [
        self::UNKNOWN   => 'unknown',
        self::MALE      => 'male',
        self::FEMALE    => 'female',
    ];

    const GENDER_COLOR_OPTIONS = [
        self::UNKNOWN   => 'info',
        self::MALE      => 'danger',
        self::FEMALE    => 'success',
    ];

    const GENDER_ZH_OPTIONS = [
        self::UNKNOWN   => '未知',
        self::MALE      => '男',
        self::FEMALE    => '女',
    ];

    /**
     * add by Richer 于 2022年4月2日10:08:26 登录方式
     */
    const ACCOUNT_PASSWORD_LOGIN        = 'account-password';
    const QUICK_LOGIN                   = 'quick';
    const WECHAT_APPLET_NICKNAME_LOGIN  = 'wechat-applet-nickname';
    const WECHAT_APPLET_MOBILE_LOGIN    = 'wechat-applet-mobile';
    const WECHAT_OFFICIAL_ACCOUNT_AUTHORIZED_LOGIN = 'wechat-official-account-authorized';
    const LOGIN_TYPE_OPTIONS = [
        self::QUICK_LOGIN                   => '快捷登录',
        self::ACCOUNT_PASSWORD_LOGIN        => '账号密码登录',
        self::WECHAT_APPLET_NICKNAME_LOGIN  => '微信小程序昵称登录',
        self::WECHAT_APPLET_MOBILE_LOGIN    => '微信小程序手机号登录',
        self::WECHAT_OFFICIAL_ACCOUNT_AUTHORIZED_LOGIN => '微信公众号授权登录',
    ];

    /**
     * 用户角色
     */
    const HEADER  = 'header';
    const FARMER  = 'farmer';
//    const MEMBER  = 'member';
    const SCORER    = 'scorer';
    const LEADER  = 'leader';
    const ROLE_TYPE_OPTIONS = [
        self::HEADER    => '户主',
        self::FARMER    => '成员',
        self::SCORER    => '组员',
//        self::MEMBER    => '组员',
        self::LEADER    => '组长',
    ];
    const FARMER_ROLE_OPTIONS = [
        self::HEADER    => '户主',
        self::FARMER    => '成员',
    ];
    const SCORER_ROLE_OPTIONS = [
        self::LEADER    => '组长',
        self::SCORER    => '组员',
//        self::MEMBER    => '组员',
    ];
    const ROLE_TYPE_COLOR_OPTIONS = [
        self::HEADER  => 'primary',
        self::FARMER  => 'primary',
        self::SCORER  => 'warning',
//        self::MEMBER  => 'warning',
        self::LEADER  => 'danger',
    ];

    const FARMER_OPTIONS = [
        self::HEADER ,self::FARMER
    ];

    const SCORER_OPTIONS = [
//        self::MEMBER ,
        self::SCORER ,
        self::LEADER
    ];


    /**
     * 列表查询字段
     *
     * @var array
     */
    const LIST_QUERY_COLUMNS = ['id','pid','username','name','email','mobile'];

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'id','pid','username','name','email','mobile', 'gender','nickname', 'avatar', 'openid','status','role',
        'registered_at','registered_ip','times'
    ];

    /**
     * 访问器被附加到模型数组的形式。
     *
     * @var array
     */
    protected $appends = ['role_show', 'status_show', 'gender_show'];

    /**
     * Get the identifier that will be stored in the subject claim of the JWT.
     *
     * @return mixed
     */
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    /**
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return ['role' => 'user'];
    }

    /**
     * 获取性别的中文显示
     *
     * @return mixed
     */
    public function getGenderShowAttribute()
    {
        return Arr::get(self::GENDER_ZH_OPTIONS, $this->gender ? : self::UNKNOWN);
    }

    /**
     * 获取角色的中文显示
     *
     * @return mixed
     */
    public function getRoleShowAttribute()
    {
        return Arr::get(User::ROLE_TYPE_OPTIONS, $this->role ? : User::SCORER);
    }

    /**
     * 代码集:主要为laravel-admin select组件使用
     *
     * @param string $role
     * @param int $id
     * @return array
     */
    public static function getSelectOptions($role = '', $id = 0): array
    {
        if (!$id) {
            $id = 0;
        }
         $query = User::where('status', config('constants.STATUS_OK'));
        if ($role) {
            $query = $query->where('role', $role);
        }
//        if ($id) {
//            $query = $query->where('role', $role)->where(function ($query) {
//                $query->where('group_id', 0)->orWhere('group_id')
//            });
//        }
        $query->where('group_id', $id);

        $models = $query->latest()->get();
//        $models = User::where('status', config('constants.STATUS_OK'))->latest()->get();
        $options = [];
        foreach ($models as $model) {
            $options[$model->id] = $model->name . '('.$model->mobile.')';
        }

        return $options;
    }

    /**
     * 根据Id批量更新数据,可以放在model里面,使得每个model都是调用这个方法
     *
     * @param array $multipleData 数据
     *
     * @return bool
     * @throws ValidationException
     * @author Richer
     */
    public function updateBatch($multipleData = array())
    {
        $tableName = $this->getTable();
        if (!is_array($multipleData)) {
            throw new ValidationException('must be an array', null, '6001');
        }

        foreach ($multipleData as &$row) {
            if (!array_key_exists('id', $row)) {
                throw new ValidationException('参数错误,缺少主键', null, '6001');
            }
            //$row[Model::FIELD_UPDATED_AT] = Carbon::now();
        }

        if ($tableName && !empty($multipleData)) {
            $updateColumn  = array_keys(Arr::first($multipleData));
            $referenceColumn = Arr::first($updateColumn);
            unset($updateColumn[0]);
            $whereIn = "";
            $q = "UPDATE " . $tableName . " SET ";
            foreach ($updateColumn as $uColumn) {
                $q .= $uColumn . " = CASE ";
                foreach ($multipleData as $data) {
                    $q .= "WHEN " . $referenceColumn . " = " . $data[$referenceColumn] . " THEN '" . $data[$uColumn] . "' ";
                }
                $q .= "ELSE " . $uColumn . " END, ";
            }
            foreach ($multipleData as $data) {
                $whereIn .= "'" . $data[$referenceColumn] . "', ";
            }

            $q = rtrim($q, ", ") . " WHERE " . $referenceColumn . " IN (" . rtrim($whereIn, ', ') . ")";


            return DB::update(DB::raw($q));
        } else {
            return false;
        }
    }
}