<?php
/**
 *  ╔═══════════════════════════════════════════════════╗
 *  ║                                                   ║
 *  ║     ██╗  ██╗   █████╗    ██████╗                  ║
 *  ║     ██║  ██║  ██╔══██╗  ██╔═══██╗                 ║
 *  ║     ███████║  ███████║  ██║   ██║                 ║
 *  ║     ██╔══██║  ██╔══██║  ██║   ██║                 ║
 *  ║     ██║  ██║  ██║  ██║  ╚██████╔╝   SNS           ║
 *  ║                                                   ║    
 *  ║                                                   ║    
 *  ║     © 2023 HaoSNS™ All Rights Reserved            ║
 *  ║     官方网站: https://www.haosns.com                *
 *  ║     本代码由赣州乐易网络科技有限公司®提供             *
 *  ║                                                    *
 *  ║   未经授权禁止复制、传播或用于其他商业目的            *
 *  ║                                                   ║
 *  ╚═══════════════════════════════════════════════════╝
 */



namespace app\common\model;

use app\common\enum\OrderEnum;
use app\common\enum\YesNoEnum;
use app\common\service\FileService;
use think\model\concern\SoftDelete;

class User extends BaseModel
{
    // use SoftDelete;
    // protected $deleteTime = 'delete_time';

    public $queryFake = false;

    public function queryFake()
    {
        $this->queryFake=true;
        return $this;
    }

    protected function initialize()
    {
        parent::initialize();

        if (!$this->queryFake) {
            $this->where('is_fake_user', 0);
        }
    }

    public function fakeUserOwner()
    {
        return $this->hasOne(User::class,'id','fake_user_owner_id')->field('id,nickname,avatar');
    }

    public function label()
    {
        // 参数说明：
        // 第一个参数：关联模型类名
        // 第二个参数：中间表名（如果没有中间表，可以省略）
        // 第三个参数：外键名（中间表中关联B表的字段）
        // 第四个参数：关联键名（中间表中关联A表的字段）

        return $this->hasMany(UserLabelRecord::class, 'user_id','id')->with('labelItem');
    }

    public function merchant()
    {
        return $this->hasOne(Merchant::class,'user_id','id');
    }
    
    /**
     * 查询当前vip
     */
    public function currentVip()
    {
        return $this->hasOne(VipLevel::class,'id','vip_level_id');
    }

    public function vipInfo()
    {
        return $this->hasOne(VipLevel::class,'id','vip_level_id');
    }

    public function chatGroup()
    {
        return $this->hasMany(ChatGroup::class,'create_by_user_id','')->field('id,name,desc,price,visit_level,longitude,latitude,province,city,district,county,area,address');
    }

    //多对多关联
    public function userLabelIndex()
    {
        return $this->belongsToMany(UserLabel::class,UserLabelIndex::class,'label_id','user_id')->field('name');
    }


    //用户信息搜索
    public function searchKeywordAttr($query, $value, $data)
    {
        if ($value) {
            $query->where('sn|nickname|mobile|id', 'like', '%' . $value . '%');
        }
    }

     //等级搜索
    public function searchLevelAttr($query, $value, $data)
    {
        if ($value) {
            // 获取指定等级的经验区间
            $currentLevel = \app\common\model\UserLevel::find($value);
            if ($currentLevel) {
                $minExp = (int)$currentLevel->experience;
                // 获取下一个等级的经验门槛作为上限
                $nextLevelExp = \app\common\model\UserLevel::where('experience', '>', $minExp)
                    ->order('experience asc, rank asc')
                    ->value('experience');

                $query->where('user_integral', '>=', $minExp);
                if ($nextLevelExp !== null) {
                    $query->where('user_integral', '<', (int)$nextLevelExp);
                }
            } else {
                $query->where('level', '=', $value);
            }
        }
    }

    //标签搜索
    public function searchLabelIdAttr($query, $value, $data)
    {
        if ($value) {
            $userIds = UserLabelIndex::where(['label_id' => $value])->column('user_id');
            $query->where('id', 'in', $userIds);
        }
    }

    //注册来源
    public function searchSourceAttr($query, $value, $data)
    {
        if ($value) {
            $query->where('register_source', '=', $value);
        }
    }

    //消费金额搜索
    public function searchMinAmountAttr($query, $value, $data)
    {
        if ($value) {
            $query->where('total_order_amount', '>=', $value);
        }
    }

    //消费金额搜索
    public function searchMaxAmountAttr($query, $value, $data)
    {
        if ($value) {
            $query->where('total_order_amount', '<=', $value);
        }
    }

    //注册时间筛选
    public function searchCreateStartTimeAttr($query, $value, $data)
    {
        if ($value) {
            $query->where('create_time', '>=', $value);
        }
    }

    //注册时间筛选
    public function searchCreateEndTimeAttr($query, $value, $data)
    {
        if ($value) {
            $query->where('create_time', '<=', $value);
        }
    }

    //禁用状态搜索
    public function searchDisableAttr($query, $value, $data)
    {
        if (in_array($value, [0, 1])) {
            $query->where('disable', '=', $value);
        }
    }

    //关联用户授权模型
    public function userAuth()
    {
        return $this->hasOne(UserAuth::class, 'user_id');

    }

      //关联用户等级模型
    public function userLevel()
    {
        return $this->hasOne(UserLevel::class, 'id', 'level');
    }

    /**
     * @notes 动态校准等级获取器
     * 无论数据库level存的是几，显示时永远根据积分动态计算正确等级
     */
    public function getUserLevelAttr($value)
    {
        // 1. 如果没有等级关联，尝试根据当前积分动态寻找
        $integral = (int)($this->getAttr('user_integral') ?? 0);
        
        // 2. 获取所有等级门槛
        $levelList = \think\facade\Db::name('user_level')->order('rank asc')->select()->toArray();
        if (empty($levelList)) {
            return $value;
        }

        // 3. 实时计算应该属于哪个等级
        $correctLevelData = $levelList[0];
        foreach ($levelList as $lvl) {
            if ($integral >= (int)$lvl['experience']) {
                $correctLevelData = $lvl;
            } else {
                break;
            }
        }

        // 4. 返回符合当前积分的等级模型对象
        return new UserLevel($correctLevelData);
    }

    public function getLevelAttr($value)
    {
        // 实时纠正 level 字段返回的值
        $integral = (int)($this->getAttr('user_integral') ?? 0);
        $levelList = \think\facade\Db::name('user_level')->order('rank asc')->column('id', 'experience');
        
        $correctLevelId = array_values($levelList)[0];
        foreach ($levelList as $exp => $id) {
            if ($integral >= (int)$exp) {
                $correctLevelId = $id;
            } else {
                break;
            }
        }
        return $correctLevelId;
    }



    /**
     * @notes 头像获取器 - 用于头像地址拼接域名
     * @param $value
     * @return string
     */
    public function getAvatarAttr($value)
    {
        return trim($value) ? FileService::getFileUrl($value) : '';
    }

        /**
     * @notes 头像获取器 - 用于头像地址拼接域名
     * @param $value
     * @return string
     */
    public function getHomeBgAttr($value)
    {
        if(!$value || empty($value)){
            return null;
        }
        
        return trim($value) ? FileService::getFileUrl($value) : '';
    }

    //最后登录时间格式化
    public function getLoginTimeAttr($value)
    {
        if($value){
            return date('Y-m-d H:i:s', $value);
        }
        return '';
    }

    /**
     * @notes 一个用户都有一个分销表，一对一关联
     * @return \think\model\relation\HasOne
     */
    public function distribution()
    {
        return $this->hasOne(Distribution::class, 'user_id', 'id')
            ->field('user_id,first_leader,code,earnings');
    }

    /**
     * @notes 获取用户昵称
     * @param $userId
     * @return mixed|string
     */
    public static function getNickname($userId)
    {
        $user = self::findOrEmpty($userId)->toArray();
        if ($user) {
            return $user['nickname'];
        }
        return '';
    }

    /**
     * @notes 获取用户粉丝数量(一级/二级)
     * @param $userId
     * @return int
     */
    public static function getFans($userId)
    {
        return self::whereOr([
            'first_leader' => $userId,
            'second_leader' => $userId
        ])->count();
    }

    /**
     * @notes 粉丝中有多少人是分销商
     * @param $userId
     * @return int
     */
    public static function getFansDistribution($userId)
    {
        $userIds = self::whereOr([
            'first_leader' => $userId,
            'second_leader' => $userId
        ])->column('id');
        return Distribution::where([
            ['user_id', 'in', $userIds],
            ['is_distribution', '=', YesNoEnum::YES],
        ])->count();
    }

    /**
     * @notes 获取用户一级粉丝数量
     * @param $userId
     * @return int
     */
    public static function getLevelOneFans($userId)
    {
        return self::where('first_leader', $userId)->count();
    }

    /**
     * @notes 一级粉丝中有多少是分销商
     * @param $userId
     * @return int
     */
    public static function getLevelOneFansDistribution($userId)
    {
        $userIds =  self::where('first_leader', $userId)->column('id');
        return Distribution::where([
            ['user_id', 'in', $userIds],
            ['is_distribution', '=', YesNoEnum::YES],
        ])->count();
    }

    /**
     * @notes 获取用户二级粉丝数量
     * @param $userId
     * @return int
     */
    public static function getLevelTwoFans($userId)
    {
        return self::where('second_leader', $userId)->count();
    }

    /**
     * @notes 二级粉丝中有多少是分销商
     * @param $userId
     * @return int
     */
    public static function getLevelTwoFansDistribution($userId)
    {
        $userIds =  self::where('second_leader', $userId)->column('id');
        return Distribution::where([
            ['user_id', 'in', $userIds],
            ['is_distribution', '=', YesNoEnum::YES],
        ])->count();
    }

    /**
     * @notes 用户粉丝数量(一级/二级)获取器
     * @param $value
     * @return int
     */
    public function getFansAttr($userId)
    {
        return self::getFans($userId);
    }

    /** 用户已支付订单总金额获取器
     * @notes
     * @param $userId
     * @return float
     */
    public function getOrderAmountAttr($userId)
    {
        return Order::where(['user_id' => $userId, 'pay_status' => YesNoEnum::YES])->sum('order_amount');
    }

    /**
     * @notes 用户已支付订单总数量获取器
     * @param $userId
     * @return int
     */
    public function getOrderNumAttr($userId)
    {
        return Order::where(['user_id' => $userId, 'pay_status' => YesNoEnum::YES])->count();
    }

    /**
     * @notes 性别获取器
     * @param $value
     * @param $data
     * @return string
     */
    public function getSexAttr($value, $data)
    {
        switch ($value) {
            case 0:
                return '未知';
            case 1:
                return '男';
            case 2:
                return '女';
        }
    }

    /**
     * @notes 生日获取器
     * @param $value
     * @param $data
     * @return false|string
     */
    public function getBirthdayAttr($value, $data)
    {
        if ($value) {
            return date('Y-m-d', $value);
        }
        return '';
    }

    /**
     * @notes 头像修改器
     * @param $value
     * @return mixed
     */
    public function setAvatarAttr($value)
    {
        return FileService::setFileUrl($value);
    }

    /**
     * @notes 用户收益获取器
     * @param $value
     * @return int
     */
    public function getUserEarningsAttr($value)
    {
        return empty($value) ? 0 : $value;
    }

    /**
     * @notes 邀请人信息
     * @param $id
     * @return array
     */
    public static function getInviterInfo($inviterId, $userId)
    {
        $inviter = self::findOrEmpty($inviterId)->toArray();
        if (empty($inviter)) {
            $info = '';
        } else {
            $info = $inviter['nickname'] . '(' . $inviter['sn'] .')';
        }
        $count = self::where('inviter_id', $userId)->count();

        return [
            'name' => $info,
            'num' => $count
        ];
    }

    /**
     * @notes 获取上级分销商
     * @param $id
     * @return string[]
     */
    public static function getFirstLeader($id)
    {
        $user = self::findOrEmpty($id)->toArray();
        if (empty($user)) {
            $info = '系统';
        } else {
            $info = $user['nickname'] . '(' . $user['sn'] .')';
        }
        return [
            'name' => $info
        ];
    }

}