<?php

namespace app\model;
use support\think\Db;

/**
 * 用户模型
 * @package app\model\User
 *
 * @property integer $id 主键(ID) - 主键
 * @property integer $role_id 角色ID
 * @property integer $parent_id 推荐人
 * @property integer $group 用戶分組
 * @property string $username 用户名
 * @property string $nickname 昵称
 * @property string $password 密码
 * @property string $trade_password 交易密码
 * @property string $sex 性别
 * @property string $avatar 头像
 * @property string $email 邮箱
 * @property string $mobile 手机
 * @property integer $level 等级
 * @property string $birthday 生日
 * @property float $money 余额(元)
 * @property float $score 积分
 * @property float $currency1 无注释
 * @property float $currency2 无注释
 * @property float $currency3 无注释
 * @property float $currency4 无注释
 * @property float $currency5 无注释
 * @property float $currency6 无注释
 * @property float $currency7 无注释
 * @property float $currency8 无注释
 * @property float $currency9 无注释
 * @property integer $email_verify 邮箱认证
 * @property integer $mobile_verify 手机认证
 * @property integer $realname_verify 实名认证
 * @property string $safe_email 安全邮箱
 * @property integer $loginfailure 登录失败的次数
 * @property integer $last_time 登录时间
 * @property string $last_ip 登录ip
 * @property integer $join_time 注册时间
 * @property string $join_ip 注册ip
 * @property string $totp_secret totp_secret
 * @property integer $expire_at 过期时间
 * @property integer $active 激活状态
 * @property string $invite_code 邀请码
 * @property integer $created_at 创建时间
 * @property integer $updated_at 更新时间
 * @property integer $status 状态
 * Strings methods
 * @method static bool money(int $user_id,float $amount, \app\enum\BalanceType $type, string $memo = null)
 * 用户余额
 * @method static bool score(int $user_id,float $amount, \app\enum\BalanceType $type, string $memo = null)
 * 用户积分
 * @method static bool currency1(int $user_id,float $amount, \app\enum\BalanceType $type, string $memo = null)
 * 调研币
 *  @method static bool currency2(int $user_id,float $amount, \app\enum\BalanceType $type, string $memo = null)
 * 
 * @method static bool currency3(int $user_id,float $amount, \app\enum\BalanceType $type, string $memo = null)
 * 
 * @method static bool currency4(int $user_id,float $amount, \app\enum\BalanceType $type, string $memo = null)
 * 
 * @method static bool currency5(int $user_id,float $amount, \app\enum\BalanceType $type, string $memo = null)
 * 
 * @method static bool currency6(int $user_id,float $amount, \app\enum\BalanceType $type, string $memo = null)
 * 可领取指标
 * @method static bool currency7(int $user_id,float $amount, \app\enum\BalanceType $type, string $memo = null)
 * 待分配指标
 * @method static bool currency8(int $user_id,float $amount, \app\enum\BalanceType $type, string $memo = null)
 * 已分配指标
 * @method static bool currency9(int $user_id,float $amount, \app\enum\BalanceType $type, string $memo = null)
 * 未通过指标
 * @method static bool transform($from_currency,$to_currency，int $user_id,float $amount, \app\enum\BalanceType $type, string $memo = null)
 */
class User extends Base
{
    use \think\model\concern\SoftDelete;
    public static function onAfterInsert($row){
        $res = request()->IM->user->userRegister($row->id,$row->nickname,cdnurl($row->avatar));
    }
    public static function onAfterUpdate($row){
        $changeData = $row->getChangedData();
        $orgData = $row->getOrigin();
        if(isset($changeData['avatar']) || isset($changeData['nickname'])){
            $sdata  = [
                'nickname'  =>  $row->nickname,
                'faceURL'   =>  cdnurl($row->avatar)
            ];
            request()->IM->user->updateUserInfo($row->id,$sdata);
        }
        if(isset($changeData['status']) || $changeData['status'] == '0'){
            request()->IM->user->forceLogout($row->id);
        }
    }
    public static function onAfterDelete($row)
    {
        Db::name('address')->where('user_id',$row->id)->delete();
        Db::name('recharge')->where('user_id',$row->id)->delete();
        Db::name('record')->where('user_id',$row->id)->delete();
        Db::name('withdrawl')->where('user_id',$row->id)->delete();
        Db::name('user_extend')->where('user_id',$row->id)->delete();
        Db::name('user_team')->where('descendant_id|ancestor_id','=',$row->id)->delete();
        Db::name('withdrawl')->where('user_id',$row->id)->delete();
        foreach(Config('site.allow_currencys') as $currency){
            (new \app\model\BalanceLog)->setSuffix('_'.$currency)->where('user_id',(int)$row->id)->delete();
        }
        request()->IM->user->forceLogout($row->id);
    }
    public function role()
    {
        return $this->belongsTo('\\app\\model\\UserRole', 'role_id', 'id');//->bind(['name']);
    }
    public function realname()
    {
        return $this->hasOne('\\app\\model\\Realname', 'id', 'user_id');//->bind(['name']);
    }
    /**
     * 扩展属性
     * @param int $user_id 用户ID
     * @return \think\model\relation\BelongsTo 用户扩展关联关系
     */
    public function extend()
    {
        return $this->belongsTo('UserExtend', 'user_id', 'id');//->setEagerlyType(0);
    }

    // 定义与 UserTeam 的关联关系，假设用户的 id 对应 UserTeam 表中的 ancestor_id
    public function team()
    {
        return $this->hasMany(UserTeam::class, 'ancestor_id', 'id');
    }
    function setExpireAtAttr($v){
        if($v && strpos($v,'-')){
            return strtotime($v);
        }
        return $v;
    }
    public static function transform($from_currency,$to_currency,$user_id,$amount,\app\enum\BalanceType $type,$memo=null){
        
        if(!in_array($from_currency,Config('site.allow_currencys'))){
            abort(__('Incorrect from_currency:%currency%',['%currency%'=>$from_currency]));
        }
        if(!in_array($to_currency,Config('site.allow_currencys'))){
            abort(__('Incorrect to_currency:%currency%',['%currency%'=>$to_currency]));
        }
        $time = time();
        $user = self::lock(true)->where('id',$user_id)->find();
        if(!$user){
            throw new \Exception(__('User not found'));
        }
        $from_after = bcadd($user->{$from_currency} , -$amount,4);
        $to_after = bcadd($user->{$to_currency} , $amount,4);
        if($to_after<0 || $from_after<0){
            abort(__('not enougth to currency'));
        } 
        $from_logData = [
            'user_id'               => $user_id.'',
            'currency'              => $from_currency,
            'amount'                => -$amount.'',
            'before'                => $user->{$from_currency}.'',
            'after'                 => $from_after.'',
            'type'                  => $type->value,
            'created_at'            => $time.'',
            'memo'                  =>  $memo
        ];
        $to_logData = [
            'user_id'               => $user_id.'',
            'currency'              => $to_currency,
            'amount'                => $amount.'',
            'before'                => $user->{$to_currency}.'',
            'after'                 => $to_after.'',
            'type'                  => $type->value,
            'created_at'            => $time.'',
            'memo'                  =>  $memo
        ];
        $user->{$from_currency} = $from_after;
        $user->{$to_currency} = $to_after;
        $user->save();

        // 写入日志
        BalanceLog::create($to_logData);
        BalanceLog::create($from_logData);
    }
    /**
     * 变更会员余额
     * @param int    $score   积分
     * @param int    $user_id 会员ID
     * @param string $memo    备注
     */
    public static function _setBalance($currency,$user_id,$amount,\app\enum\BalanceType $type,$memo=null){
        //cp($currency,$user_id,$amount,$type->getDescription(),$memo);
        if(!in_array($currency,Config('site.allow_currencys'))){
            abort(__('Incorrect currency:%currency%',['%currency%'=>$currency]));
        }
        if(!$currency){
            abort(__('Incorrect currency'));
        }
        if(!$user_id){
            abort(__('Incorrect parameter user'));
        }
        if(!$amount){
            abort(__('Incorrect amount'));
        }
        $user = self::lock(true)->where('id',$user_id)->find();
        $after = bcadd($user->{$currency}, $amount, 8);
        if($amount < 0 && $after < 0){
            abort(__('Insufficient user balance'));
        }
        $logData = [
            'user_id'               => $user_id.'',
            'currency'              => $currency,
            'amount'                => $amount.'',
            'before'                => '0',
            'after'                 => '0',
            'type'                  => $type->value,
            'created_at'            => time().'',
            'memo'  =>  $memo
        ];
        $logData['before'] = $user->{$currency};
        $user->{$currency} = $after;
        $logData['after'] = $user->{$currency};
        $user->save();
        
        // 写入日志
        BalanceLog::create($logData);
    }
     
    public static function __callStatic($method, $args)
    {
        $currency = strtolower($method);
        if(in_array($currency,Config('site.allow_currencys'))){
            return self::_setBalance($currency,$args[0],$args[1],$args[2],$args[3]);
        }else{
            return parent::__callStatic($method, $args);
        }
    }
    /**
     * 扩展属性
     * @param int $user_id 用户ID
     * @return \think\model\relation\BelongsTo 用户扩展关联关系
     */
    public function referrer()
    {
        return $this->belongsTo('User', 'parent_id', 'id');//->setEagerlyType(0);
    }
}