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

namespace app\api\controller;
use app\common\enum\NoticeEnum;
use app\api\{
    logic\UserLogic,
    validate\UserValidate,
    validate\SetUserInfoValidate
};


/**
 * 用户控制器
 * Class UserController
 * @package app\api\controller
 */
class User extends BaseShopController
{
    public array $notNeedLogin = ['resetPasswordCaptcha', 'resetPassword','home','follow','fans'];

    /**
     * @notes 个人中心
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function centre()
    {
        $data = (new UserLogic)->centre($this->userInfo);
        $ip = $this->request->ip();
        if($ip == $data['ip']){
            try {
                
                $user = \app\common\model\User::where('id',$this->userId)->find();
                $ip = $_SERVER['REMOTE_ADDR'];
                $ip_address = '';
                // 初始化，指定QQWry.dat文件路径
                $qqwry = new \app\common\service\QQWry('qqwry.dat');
                // 查询IP地理位置
                $location = $qqwry->getLocation($ip);
                $ip_address = $location['country'];
                $user->ip = $ip;
                $user->ip_address = $ip_address;
                $user->save();

            } catch (\Exception $e) {
                // echo "发生错误: " . $e->getMessage();
            }
        }
        // 访客数量
        $data['home_visitor_count'] = \app\common\model\HomeVisitor::where([
            'visited_user_id'=>$this->userId,
        ])->count();
        // 新增粉丝,今天
        $data['fans_count']=\app\common\model\UserFollow::with(['fans'])
        ->where(['follow_user_id'=>$this->userId])
        ->where('create_time','>',strtotime('today'))
        ->count();

        return $this->success('', $data);
    }

    /**
     * @notes 个人主页
     */
    public function home()
    {
        $params = $this->request->get();
        $data = (new UserLogic)->home($this->userInfo,$params);
        $data['online_status'] = 0;
        $data['online_time'] = 0;
        $data['hone_visitor_count'] = \app\common\model\HomeVisitor::where([
            'visited_user_id'=>$params['user_id'],
        ])->count();
        
        $data['online']=checkOnline($data['id']);

        $data['age'] = !empty($data['birth']) ? date('Y') - date('Y', $data['birth']) : null;

        // 记录访问记录
        $this->HoneVisitor($data['id']);
        
        return $this->success('', $data);
    }

    /**
     * 记录主页访问你记录
     * @return void
     */
    private function HoneVisitor($id)
    {
        $data = [
            'user_id'=>$this->userId,
            'visited_user_id'=>$id,
        ];
        
        $homeVisitor = \app\common\model\HomeVisitor::where($data)->find();
       
        if($homeVisitor){
            $homeVisitor->update_time = time();
            $homeVisitor->save();
        }else{
            \app\common\model\HomeVisitor::create($data);
        };
        
    }

    /**
     * 查询对方的访客记录
     */
    public function honeVisitorList($user_id)
    {
        $user = \app\common\model\User::find($user_id);
        if($user->private_visitor == 1){
            return show(config('status.error'),'对方设置了隐私');
        };
        
        $list = \app\common\model\HomeVisitor::with(['user'])
        ->order('update_time','desc')
        ->where('visited_user_id',$user_id)->paginate(30);

        return show(config('status.success'),'访客记录',$list);
       
    }
    

    /**
     * 对方关注的
     */
    public function follow($user_id)
    {

        $user = \app\common\model\User::find($user_id);
        if($user->private_follow == 1){
            return show(config('status.error'),'对方设置了隐私');
        }; 
        
        $list = \app\common\model\UserFollow::with(['user'])
            ->where(['user_id'=>$user_id])
            ->order('id', 'desc')
            ->paginate(20);
        
        return show(config('status.success'),'关注列表数据',$list);
    }

    /**
     * 对方粉丝
     */
    public function fans($user_id)
    {
        $user = \app\common\model\User::find($user_id);
        if($user->private_fans == 1){
            return show(config('status.error'),'对方设置了隐私');
        };
        
        $list = \app\common\model\UserFollow::with(['fans'])
            ->where(['follow_user_id'=>$user_id])
            ->order('id', 'desc')
            ->paginate(20);
        
        return show(config('status.success'),'关注列表数据',$list);
    }

    

    /**
     * @notes 设置用户认证信息
     * @return \think\response\Json
     */
    public function setUserCertification()
    {
        $params = (new UserValidate())->post()->goCheck('userCertification');
        $result = (new UserLogic)->setUserCertification($this->userId, $params);
        if( $result){
            return $this->success('申请成功', [],1,1);
        }
        return $this->fail(UserLogic::getError());
    }


    /**
     * @notes 设置用户信息
     * @return \think\response\Json
     */
    public function setInfo()
    {
        $params = (new SetUserInfoValidate())->post()->goCheck(null, ['id' => $this->userId]);
        
        // 铭感词库检查
        if($params['field'] == 'nickname'){
            checkDangerTxt($params['value']);
        };

        (new UserLogic)->setInfo($this->userId, $params);
        return $this->success('操作成功', [],1,1);
    }

    /**
     * @notes 发送验证码 - 绑定手机号
     */
    public function bindMobileCaptcha()
    {
        $params = (new UserValidate())->post()->goCheck('bindMobileCaptcha');
        $code = mt_rand(1000, 9999);
        $result = event('Notice', [
            'scene_id' =>  NoticeEnum::BIND_MOBILE_CAPTCHA,
            'params' => [
                'user_id' => $this->userId,
                'code' => $code,
                'mobile' => $params['mobile']
            ]
        ]);
        if ($result[0] === true) {
            return $this->success('发送成功');
        }

        return $this->fail($result[0], [], 0, 1);
    }

    /**
     * @notes 发送验证码 - 变更手机号
     */
    public function changeMobileCaptcha()
    {
        $params = (new UserValidate())->post()->goCheck('changeMobileCaptcha');
        $code = mt_rand(1000, 9999);
        $result = event('Notice', [
            'scene_id' =>  NoticeEnum::CHANGE_MOBILE_CAPTCHA,
            'params' => [
                'user_id' => $this->userId,
                'code' => $code,
                'mobile' => $params['mobile']
            ]
        ]);
        if ($result[0] === true) {
            return $this->success('发送成功');
        }

        return $this->fail($result[0], [], 0, 1);
    }

    /**
     * @notes 绑定手机号
     * @return \think\response\Json
     */
    public function bindMobile()
    {
        $params = (new UserValidate())->post()->goCheck('bindMobile');
        $params['id'] = $this->userId;
        $result = UserLogic::bindMobile($params);
        if($result) {
            return $this->success('绑定成功', [], 1, 1);
        }
        return $this->fail(UserLogic::getError());
    }

    /**
     * @notes 用户等级
     * @return \think\response\Json
     */
    public function userLevel()
    {
        $userLevel = (new UserLogic)->userLevel($this->userId);
        return $this->success('', $userLevel);
    }

    /**
     * @notes 判断用户是否已设置支付密码
     * @return \think\response\Json
     */
    public function hasPayPassword()
    {
        $result = UserLogic::hasPayPassword($this->userId);
        return $this->data($result);
    }


    /**
     * @notes 设置/修改交易密码
     * @return \think\response\Json
     */
    public function setPayPassword()
    {
        $params = (new UserValidate())->post()->goCheck('setPayPassword');
        $params['user_id'] = $this->userId;
        $result = UserLogic::setPayPassword($params);
        if($result) {
            return $this->success('修改成功',[], 1, 1);
        }
        return $this->fail(UserLogic::getError());
    }

    /**
     * @notes 发送验证码 - 重置支付密码
     */
    public function resetPayPasswordCaptcha()
    {
        $params = (new UserValidate())->post()->goCheck('resetPayPasswordCaptcha');
        $code = mt_rand(1000, 9999);
        $result = event('Notice', [
            'scene_id' =>  NoticeEnum::FIND_PAY_PASSWORD_CAPTCHA,
            'params' => [
                'user_id' => $this->userId,
                'code' => $code,
                'mobile' => $params['mobile']
            ]
        ]);
        if ($result[0] === true) {
            return $this->success('发送成功');
        }

        return $this->fail($result[0], [], 0, 1);
    }

    /**
     * @notes 重置支付密码
     * @return \think\response\Json
     */
    public function resetPayPassword()
    {
        $params = (new UserValidate())->post()->goCheck('resetPayPassword', ['id' => $this->userId]);
        $result = UserLogic:: resetPayPassword($params);
        if($result) {
            return $this->success('重置支付密码成功', [], 1, 1);
        }
        return $this->fail(UserLogic::getError());
    }

    /**
     * @notes 发送验证码 - 重置登录密码
     */
    public function resetPasswordCaptcha()
    {
        $params = (new UserValidate())->post()->goCheck('resetPasswordCaptcha');
        $code = mt_rand(1000, 9999);
        $result = event('Notice', [
            'scene_id' =>  NoticeEnum::FIND_LOGIN_PASSWORD_CAPTCHA,
            'params' => [
                'user_id' => $this->userId,
                'code' => $code,
                'mobile' => $params['mobile']
            ]
        ]);
        if ($result[0] === true) {
            return $this->success('发送成功');
        }

        return $this->fail($result[0], [], 0, 1);
    }

    /**
     * @notes 重置登录密码
     * @return \think\response\Json
     */
    public function resetPassword()
    {
        $params = (new UserValidate())->post()->goCheck('resetPassword');
        $result = UserLogic:: resetPassword($params);
        if($result) {
            return $this->success('重置登录密码成功', [], 1, 1);
        }
        return $this->fail(UserLogic::getError());
    }


    /**
     * @notes 钱包
     * @return \think\response\Json
     */
    public function wallet()
    {
        $result = UserLogic::wallet($this->userId);
        return $this->data($result);
    }

    /**
     * @notes 用户信息
     * @return \think\response\Json
     */
    public function info()
    {
        $result = UserLogic::info($this->userId);
        return $this->data($result);
    }

    /**
     * @notes 获取微信手机号并绑定
     * @return mixed
     */
    public function getMobileByMnp()
    {
        $params = (new UserValidate())->post()->goCheck('getMobileByMnp');
        $params['user_id'] = $this->userId;
        $result = UserLogic::getNewMobileByMnp($params);
        if($result === false) {
            return $this->fail(UserLogic::getError());
        }
        return $this->success('绑定成功', [], 1, 1);
    }

    /**
     * @notes 获取服务协议
     * @return \think\response\Json
     */
    public function getServiceAgreement()
    {
        $result = UserLogic::getServiceAgreement();
        return $this->data($result);
    }

    /**
     * @notes 获取隐私政策
     * @return \think\response\Json
     */
    public function getPrivacyPolicy()
    {
        $result = UserLogic::getPrivacyPolicy();
        return $this->data($result);
    }


    /**
     * @notes 设置登录密码
     * @return \think\response\Json
     */
    public function setPassword()
    {
        $params = (new UserValidate())->post()->goCheck('setPassword');
        $params['user_id'] = $this->userId;
        $result = UserLogic::setPassword($params);
        if($result) {
            return $this->success('设置成功',[], 1, 1);
        }
        return $this->fail(UserLogic::getError());
    }

    /**
     * @notes 修改登录密码
     * @return \think\response\Json
     */
    public function changePassword()
    {
        $params = (new UserValidate())->post()->goCheck('changePassword');
        $params['user_id'] = $this->userId;
        $result = UserLogic::changePassword($params);
        if($result) {
            return $this->success('修改成功',[], 1, 1);
        }
        return $this->fail(UserLogic::getError());
    }

    /**
     * @notes 判断用户是否设置登录密码
     * @return mixed
     */
    public function hasPassword()
    {
        $result =  UserLogic::hasPassword($this->userId);
        return $this->data([
            'has_password' => $result
        ]);
    }


     /**
     * @notes 账户注销
     * @return mixed
     */
    public function logoff()
    {
        UserLogic::setInfo($this->userId , ['field' => 'is_logoff', 'value' => 1]);
        return $this->success('注销申请成功',[], 1, 1);
    }

    /**
     * 余额提现
     */
    public function withdraw_balance()
    {
        $params = $this->request->post();

        $user = \app\common\model\User::find($this->userId);

        if($user->user_money < $params['money']){
            return show(config('status.error'),'您的余额不足');
        }

        if($params['channel'] == 'alipay_code' && !$user->withdraw_alipay_code){
            return show(config('status.error'),'请先上传支付宝收款二维码');
        }

        if($params['channel'] == 'wepay_code' && !$user->withdraw_wepay_code){
            return show(config('status.error'),'请先上传微信收款二维码');
        }

        if($params['channel'] == 'alipay_account' && !$user->withdraw_alipay_account){
            return show(config('status.error'),'请先设置支付宝账号');
        }

        if(empty($user->withdraw_alipay_account)){
            return show(config('status.error'),'请设置真实名字');
        }
        
        // 查询有无正在申请的提现记录

        \think\facade\Db::startTrans();
        try{

            //扣除余额
            $res = $user->dec('user_money', $params['money'])->save();

            // 创建提现申请
            $record = [
                "user_id"=>$this->userId,
                "type"=>"balance",
                "channel"=>$params['channel'],
                "amount"=>$params['money'],
                'status'=>0,
            ];

            $res_withdrawal = \app\common\model\UserWithdrawal::create($record);

            // 记录余额流水
            \app\common\logic\AccountLogLogic::add(
                $this->userId,
                \app\common\enum\AccountLogEnum::BW_DEC_WITHDRAWAL,//提现
                \app\common\enum\AccountLogEnum::DEC,
                $params['money'],
                $res_withdrawal->id,
            );

            \think\facade\Db::commit();

            return show(config('status.success'),'提现申请提交成功',['id'=>$res_withdrawal->id]);
        }catch(\Exception $e){
            \think\facade\Db::rollback();
            return show(config('status.error'),$e->getMessage());
        }
    }

    /**
     * 收益提现
     */
    public function withdraw_earnings()
    {
        $params = $this->request->post();

        $user = \app\common\model\User::find($this->userId);

        if($user->user_earnings < $params['money']){
            return show(config('status.error'),'收益不够提现');
        }

        if($params['channel'] == 'alipay_code' && !$user->withdraw_alipay_code){
            return show(config('status.error'),'请先上传支付宝收款二维码');
        }

        if($params['channel'] == 'wepay_code' && !$user->withdraw_wepay_code){
            return show(config('status.error'),'请先上传微信收款二维码');
        }

        if($params['channel'] == 'alipay_account' && !$user->withdraw_alipay_account){
            return show(config('status.error'),'请先设置支付宝账号');
        }

        if(empty($user->withdraw_alipay_account)){
            return show(config('status.error'),'请设置真实名字');
        }
        
        // 查询有无正在申请的提现记录

        \think\facade\Db::startTrans();
        try{

            //扣除余额
            $res = $user->dec('user_earnings', $params['money'])->save();

            // 创建提现申请
            $record = [
                "user_id"=>$this->userId,
                "type"=>"earnings",
                "channel"=>$params['channel'],
                "amount"=>$params['money'],
                'status'=>0,
            ];

            $res_withdrawal = \app\common\model\UserWithdrawal::create($record);

            // 记录余额流水
            \app\common\logic\AccountLogLogic::add(
                $this->userId,
                \app\common\enum\AccountLogEnum::BW_DEC_WITHDRAWAL,//提现
                \app\common\enum\AccountLogEnum::DEC,
                $params['money'],
                $res_withdrawal->id,
            );

            \think\facade\Db::commit();

            return show(config('status.success'),'提现申请提交成功',['id'=>$res_withdrawal->id]);
        }catch(\Exception $e){
            \think\facade\Db::rollback();
            return show(config('status.error'),$e->getMessage());
        }
    }


    /**
     * 我的提现申请列表
     * 提现记录
     */
    public function myWithdrawList()
    {
        $list = \app\common\model\UserWithdrawal::where('user_id',$this->userId)
        ->order('create_time','desc')
        ->paginate(20);

        return show(config('status.success'),$list);
    }

    /**
     * 搜索用户
     */
    public function search($nickname)
    {
        $params = $this->request->get();
        $where=[];

        if(isset($params['sex'])){
            $where[]=['sex','=',$params['sex']];
        }

        if(isset($params['sex'])){
            $where[]=['sex','=',$params['sex']];
        }

        if(isset($params['address'])){
            $where[]=['sex','like','%'.$params['sex'].'%'];
        }

        if(isset($params['district'])){
            $where[]=['district','=',$params['district']];
        }
        if(isset($params['city'])){
            $where[]=['city','=',$params['city']];
        }
        if(isset($params['province'])){
            $where[]=['province','=',$params['province']];
        }
        if(isset($params['county'])){
            $where[]=['county','=',$params['county']];
        }
        if(isset($params['area'])){
            $where[]=['area','=',$params['area']];
        }
        
        $list = \app\common\model\User::field('id,nickname,avatar')
        ->where($where)
        ->where('nickname','like','%'.$nickname.'%')->paginate(10);

        return show(config('status.success'),'',$list);
    }


    /**
     * 标签查询
     */
    public function labelList()
    {
        $list = \app\common\model\UserLabel::select()->toArray();

        return show(config('status.success'),'',$list);
    }

    /**
     * 添加标签
     */
    public function addLabel()
    {
        $params = $this->request->post();
        \app\common\model\UserLabelIndex::create([
            'user_id'=>$this->userId,
            'label_id'=>$params['label_id']
        ]);

        return show(config('status.success'),'设置成功');
    }

    /**
     * 删除标签
     */
    public function delLabel()
    {
        $params = $this->request->post();
        \app\common\model\UserLabelIndex::where([
            'id'=>$params['id'],
            'user_id'=>$this->userId
        ]);

        return show(config('status.success'),'删除成功');
    }

    /**
     * 设置定位
     */
    public function setPosition()
    {
        $params = $this->request->post();

        \app\common\model\User::where('id',$this->userId)->update([
            'longitude'=>$params['longitude'],
            'latitude'=>$params['latitude'],
            'address'=>$params['address'],//json地区详细数据
            'city'=>$params['city'],//城市
            'province'=>$params['province'],//省
            'district'=>$params['district'],//区
            'county'=>$params['county'],//县
            'area'=>$params['area'],//具体位置
        ]);

        return show(config('status.success'),'设置成功');
    }

    /**
     * 查询同城的
     */
    public function sameCity()
    {
        $user = \app\common\model\User::find($this->userId);

        if(empty($user->city)){
            return show(config('status.success'),'请先设置位置');
        }

        // 查询附近的人
        $list = \app\common\model\User::field('id,nickname,avatar,longitude,latitude,address,desc')
        ->where([
            'city'=>$user->city,
        ])->paginate(20);

        return show(config('status.success'),'',$list);
    }
    

    /**
     * 好友匹配 
     * 城市 年龄 兴趣 职业 匹配好友
     */
    public function match()
    {
        $params = $this->request->get();

        $user = \app\common\model\User::find($this->userId);

        $where = [
            ['id','!=',$this->userId],
        ];

        if($user->sex == '男'){
            $where[]=['sex','=','女'];
        }else{
            $where[]=['sex','=','男'];
        }

        if($user->birth > 0){
            $min_birth = $user->birth - 60*60*24*365 * 5;
            $max_birth = $user->birth + 60*60*24*365 * 5;

            $where[] = [$user->birth,'>',$min_birth];
            $where[] = [$user->birth,'<',$max_birth];
        }

        if(isset($params['city'])){
            $where[]=['address','like','%'.$params['city'].'%'];
        }

        $match_user = \app\common\model\User::field('id,nickname,avatar,home_bg,desc,birth,career,height,weight,province,city,district,county')
        ->where($where)
        ->orderRand()
        ->find();

        if(!$match_user){
            return \show(config('status.error'),'没有匹配到好友');
        }

        return \show(config('status.success'),'',$match_user);
    }


    /**
     * 可能认识的人/可能感兴趣的人
     */
    public function interestUser()
    {
        $users = [];
        // 1.查询我关注的
        $follows_user_ids = [];
        $follows_user = \app\common\model\UserFollow::with(['user'])
            ->where(['user_id'=>$this->userId])
            ->orderRand()
            ->limit(10)
            ->select()
            ->column('user');

        foreach($follows_user as $v){
            $follows_user_ids[]=$v['id'];
        }
        
        // 查询别人关注的
        $to_follows_user = \app\common\model\UserFollow::with(['user'])
            ->where('user_id','in',$follows_user_ids)
            ->where('user_id','!=',$this->userId)
            ->orderRand()
            ->group('follow_user_id')
            ->limit(10)
            ->select()
            ->column('user');

        foreach($to_follows_user as &$v){
            if($v['id']==$this->userId){
                unset($v);
            }
        }

        // 根据兴趣爱好或附近的人等关系推荐
        // 
        
        
        return \show(config('status.success'),'',$to_follows_user);

    }

    /**
     * 拉黑用户
     */
    public function blockUser()
    {
        $params = $this->request->post();

        \app\common\model\UserBlock::create([
            'user_id'=>$this->userId,
            'target_user_id'=>$params['target_user_id'],
        ]);

        return show(config('status.success'),'拉黑成功');

    }

    /**
     * 我的拉黑
     */
    public function myBlockUserList() 
    {
        
        $list = \app\common\model\User::field('id,nickname,avatar')
        ->where('user_id',$this->userId)
        ->order('create_time','desc')
        ->toArray();

        return show(config("status.success"),'',$list);
    }


    /**
     * 解除拉黑
     */
    public function unBlockUser()
    {
        $params = $this->request->post();

        \app\common\model\UserBlock::where([
            'user_id'=>$this->userId,
            'target_user_id'=>$params['target_user_id'],
        ])->delete();

        return show(config("status.success"),"解除拉黑成功");
        
    }

}