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


namespace app\api\controller;

use app\api\logic\ChatLogic;
use app\common\logic\ChatLogic as CommonChatLogic;
use app\api\validate\ChatGoodsValidate;
use think\facade\Db;

/**
 * 聊天相关控制器
 * Class ChatController
 * @package app\api\controller
 */
class Chat extends BaseShopController
{
    /**
     * 搜索聊天记录
     */
    public function searchMessage()
    {
        $msg = $this->request->get('msg');

        // 群聊天消息
        $mygroup_ids = \app\common\model\ChatGroupMember::where('user_id',$this->userId)
        ->where('status',1)
        ->column('id');
        $group_message = \app\common\model\ChatGroupMessage::with('fromUser')
        ->where([
            ['msg_type','=','text'],
            ['msg','like','%'.$msg.'%'],
            ['group_id','in',$mygroup_ids]
        ])
        ->order('create_time','desc')
        ->limit(0,100)
        ->select()
        ->toArray();
        $group_message_list = [];
        foreach($group_message as $g){
            $group_message_list['group_'.$g['group_id']][]=$g;
        }

        // 圈子聊天消息
        $mycircle_ids = \app\common\model\ChatTemp::where([
            ['user_id','=',$this->userId],
            ['type','=','circle_chat']
        ])
        ->column('circle_id');
        $circle_message = \app\common\model\ChatCircleMessage::with('fromUser')
        ->where([
            ['msg_type','=','text'],
            ['msg','like','%'.$msg.'%'],
            ['circle_id','in',$mycircle_ids]
        ])
        ->order('create_time','desc')
        ->limit(0,100)
        ->select()
        ->toArray();
        $circle_message_list = [];
        foreach($group_message as $g){
            $group_message_list['circle_'.$g['group_id']][]=$g;
        }
        
        // 私聊聊天消息
        $private_message = \app\common\model\ChatPrivateMessage::with(['fromUser','toUser'])
        ->where('msg','like','%'.$msg.'%')
        ->where(function($query){
            $query->where('from_id',$this->userId)
            ->whereOr('to_id',$this->userId);
        })
        ->order('id','desc')
        ->limit(0,100)
        ->select()
        ->toArray();
        $private_message_list = [];
        foreach($private_message as $p){
            $key = 'private_';
            if($p['from_id'] == $this->userId){
                $key.=$this->userId.'_'.$p['to_id'];
            }else{
                $key.=$this->userId.'_'.$p['from_id'];
            };
            $private_message_list[$key][]=$p;
        }

        return show(config('status.success'),'ok',['group'=>$group_message_list,'private'=>$private_message_list,'circle'=>$circle_message_list]);
    }

    /**
     * 发送私聊消息
     */
    public function sendPrivateMessage()
    {   
        $params = $this->request->post();
        // dd($params);

        // 判断对方有没有把你拉黑
        $user_block = \app\common\model\UserBlock::where([
            'user_id'=>$params['to_id'],
            'target_user_id'=>$this->userId,
        ])->count();
        if($user_block>0){
            return \show(config('status.error'),'对方已把你加入黑名单');
        }

        if (!isActivePluginByPluginName('voice') && $params['msg_type'] == 'voice') {
            return show(config('status.error'),'请先安装语音插件');
        }

        if($params['msg_type'] == 'text'){
            if(empty($params['msg'])){
                return show(config('status.success'),'不能为空');
            }
            checkDangerTxt($params['msg']);
        }
        
        $message = [
            'from_id' => $this->userId,
            'to_id' => $params['to_id'],
            'msg' => $params['msg'],
            'msg_type' => $params['msg_type'],
            'type' => 'private_chat',
        ];
        
        // 持久化到数据库
        $data = \app\common\model\ChatPrivateMessage::create($message);
        if(!$data){
            return show(config('status.error'),'发送失败');
        }
        $data = $data->toArray();

        // 创建临时聊天窗口
        self::bindPrivateTemp($data);

        // 推送消息
        httpPost('https://'.$_SERVER['HTTP_HOST'].':9501',$data);

        // $this->privateRead();
        
        // 发布到Redis频道
        // 连接存储改用Redis
        // $redis = new \Redis();
        // $redis->connect('127.0.0.1', 6379);
        // 往消息队列添加消息
        // $res = $redis->lpush('message_queue', json_encode($message,JSON_UNESCAPED_UNICODE));

        return show(config('status.success'),'发送成功',['data'=>$data['id']]);

    }

    /**
     * 私聊读取对方消息
     * @return void
     */
    public function privateRead($to_id)
    {
        \app\common\model\ChatPrivateMessage::update([
            'is_read'=>1
        ], [
            'from_id'=>$to_id,
            'to_id'=>$this->userId,
        ]);

        \app\common\model\ChatTemp::where([
            'user_id'=>$to_id,
            'to_id'=>$this->userId,
        ])
        ->update(['unread'=>0]);

        soketNotice($to_id,['msg_type'=>'read','msg'=>'已读','from_user_id'=>$this->userId]);

        return show(config('status.success'),'成功');
    }
    
    // public

    
    /**
     * 发送群聊消息
     */
    public function sendGroupMessage()
    {   
        $params = $this->request->post();

        if($params['msg_type'] == 'text'){
            if(empty($params['msg'])){
                return show(config('status.success'),'不能为空');
            }
            checkDangerTxt($params['msg']);
        }

        $groupInfo = \app\common\model\ChatGroup::find($params['group_id']);

        if($groupInfo->status!=1){
            return show(config('status.error'),'群已被禁言');
        }

        if($groupInfo['delete_time'] && $groupInfo['delete_time']>0){
            return show(config('status.error'),'群已解散');
        }

        // 判断有无在群里
        $res = \app\common\model\ChatGroupMember::where([
            'status'=>1,
            'user_id'=>$this->userId,
            'group_id'=>$params['group_id']
        ])->find();
        if(!$res){
            return show(config('status.error'),'你没有在群里');
        }
        
         // 添加聊天记录
         $message = [
            'from_id' => $this->userId,
            'group_id' => $params['group_id'],
            'msg' => $params['msg'],
            'msg_type' => $params['msg_type'],
            'type' => 'group_chat',
        ];
        // 持久化到数据库
        $data = \app\common\model\ChatGroupMessage::create($message);
        if(!$data){
            return show(config('status.error'),'发送失败');
        }
        $data = $data->toArray();
        $data['avatar']=$this->userInfo['avatar'];
        $data['nickname']=$this->userInfo['nickname'];
        
        // 创建临时聊天窗口
        self::bindGroupTemp($data);

        // 推送消息
        httpPost('https://'.$_SERVER['HTTP_HOST'].':9501',$data);

        return show(config('status.success'),'发送成功',['data'=>$data['id']]);
    }

    /**
     * 圈子聊天消息
     */
    public function sendCircleMessage()
    {   
        $params = $this->request->post();

        if($params['msg_type'] == 'text'){
            if(empty($params['msg'])){
                return show(config('status.success'),'不能为空');
            }
            checkDangerTxt($params['msg']);
        }

        $CircleInfo = \app\common\model\Circle::find($params['circle_id']);
        
        if($CircleInfo->chat_status!=1){
            return show(config('status.error'),'该圈子已关闭群聊');
        };

        //  添加聊天记录
         $message = [
            'from_id' => $this->userId,
            'circle_id' => $params['circle_id'],
            'msg' => $params['msg'],
            'msg_type' => $params['msg_type'],
            'type' => 'circle_chat',
        ];
        // 持久化到数据库
        $data = \app\common\model\ChatCircleMessage::create($message);
        if(!$data){
            return show(config('status.error'),'发送失败');
        }
        $data = $data->toArray();
        $data['avatar']=$this->userInfo['avatar'];
        $data['nickname']=$this->userInfo['nickname'];

        $circle_temp = \app\common\model\ChatTemp::where([
            'type'=>'circle_chat',
            'circle_id'=>$params['circle_id'],
        ])
        ->select()
        ->toArray();
        foreach($circle_temp as $v){
            if($v['user_id'] != $this->userId){
                \app\common\model\ChatTemp::where('id',$v['id'])->update(['unread'=>$v['unread']+1]);
            }else{
                \app\common\model\ChatTemp::where('id',$v['id'])->update(['update_time'=>time()]);
            }
        }

        // 推送消息
        httpPost('https://'.$_SERVER['HTTP_HOST'].':9501',$data);

        return show(config('status.success'),'发送成功',['data'=>$data['id']]);
    }


    /**
     * @notes 绑定关系
     * @param $data
     */
    public static function bindPrivateTemp($data)
    {
        // 存入我和谁的聊天记录
        $from = \app\common\model\ChatTemp::where([
            ['user_id','=',$data['from_id']],
            ['to_id','=',$data['to_id']],
            ['type','=','private_chat']
        ])->find();

        if(!$from){
            
            \app\common\model\ChatTemp::create([
                'user_id'=>$data['from_id'],
                'type'=>$data['type'],
                'to_id'=>$data['to_id'],
            ]);
        }else{
            $from->update_time = time();
            $from->save();
        }

        // 对方也存入
        $to = \app\common\model\ChatTemp::where([
            ['user_id','=',$data['to_id']],
            ['to_id','=',$data['from_id']],
            ['type','=',$data['type']]
        ])->find();
        if(!$to){
            \app\common\model\ChatTemp::create([
                'user_id'=>$data['to_id'],
                'type'=>$data['type'],
                'to_id'=>$data['from_id'],
                'unread'=>1,
            ]);
        }else{
            $to->unread = $to->unread+1;
            $to->save();
        }
    }

    public static function bindGroupTemp($data)
    {
        // 存入我和谁的聊天记录
        $from = \app\common\model\ChatTemp::where([
            ['user_id','=',$data['from_id']],
            ['group_id','=',$data['group_id']],
            ['type','=','group_chat']
        ])->find();
        
        if(!$from){
            \app\common\model\ChatTemp::create([
                'user_id'=>$data['from_id'],
                'type'=>$data['type'],
                'group_id'=>$data['group_id'],
            ]);
        }else{
            $from->update_time = time();
            $from->save();
        }

        // 所有群成员都存入一条临时消息
        // 所有群成员
        $groupMemberList = \app\common\model\ChatGroupMember::where('group_id',$data['group_id'])
        ->where('user_id','!=',$data['from_id'])
        ->select();
        foreach($groupMemberList as $v){
            $member = \app\common\model\ChatTemp::where([
                ['user_id','=',$v['user_id']],
                ['group_id','=',$data['group_id']],
                ['type','=','group_chat']
            ])->find();
            
            if(!$member){
                \app\common\model\ChatTemp::create([
                    'user_id'=>$v['user_id'],
                    'type'=>$data['type'],
                    'group_id'=>$data['group_id'],
                ]);
            }else{
                $member->unread = $member->unread+1;
                $member->save();
            }
        }

        // 对方也存入
        // $to = \app\common\model\ChatTemp::where([
        //     ['user_id','=',$data['to_id']],
        //     ['to_id','=',$data['from_id']],
        //     ['type','=',$data['type']]
        // ])->find();
        // if(!$to){
        //     \app\common\model\ChatTemp::create([
        //         'user_id'=>$data['to_id'],
        //         'type'=>$data['type'],
        //         'group_id'=>$data['group_id']??0,
        //         'to_id'=>$data['from_id']??0,
        //     ]);
        // }
    }
    

    
    /**
     * @notes 获取与用户私聊聊天记录
     * @return \think\response\Json
     * @date 2022/3/14 14:47
     */
    public function chatPrivateMessage()
    {
        $params = $this->request->get();
        return $this->success('', ChatLogic::getChatPrivateMessage($this->userId,$params['to_id']));
    }

    public function chatCircleMessage()
    {
        $params = $this->request->get();
        $data = \app\common\model\ChatCircleMessage::with('user')->where('circle_id',$params['circle_id'])->order('create_time','desc')->paginate(20)->toArray();
        // 清空未读
        \app\common\model\ChatTemp::where([
            'user_id'=>$this->userId,
            'circle_id'=>$params['circle_id'],
        ])->update(['unread'=>0]);

        foreach($data['data'] as &$v){
            if($v['msg_type']=='article'){
                $v['article'] = \app\common\model\Article::field('title,content,image')->find($v['msg']);
            }elseif($v['msg_type']=='goods'){
                $v['goods'] = \app\common\model\Article::field('name,image,min_price,content')->find($v['msg']);
            }
        }
        
        return show(config('status.success'),'圈子聊天消息',$data);
    }

    public function chatKefuMessage()
    {
        $params = $this->request->get();
        return $this->success('', ChatLogic::getChatKefuMessage($this->userId,$params['to_id']));
    }

    /**
     * 获取群聊天记录
     */
    public function chatGroupMessage()
    {
        $params = $this->request->get();
        return $this->success('', ChatLogic::getChatGroupMessage($this->userId,$params['group_id']));
    }

    /**
     * 创建圈子内临时消息窗口
     */
    public function createCircleTemp($circle_id)
    {
        $temp = \app\common\model\ChatTemp::where([
            'user_id'=>$this->userId,
            'circle_id'=>$circle_id,
        ])
        ->find();

        if(!$temp){
            \app\common\model\ChatTemp::create([
                'user_id'=>$this->userId,
                'circle_id'=>$circle_id,
                'type'=>'circle_chat',
            ]);
        };

        return show(config('status.success'),'创建临时消息');
    }

    /**
     * 查询单个临时消息接口
     */
    public function chatTempDetail()
    {
        $params = $this->request->get();
        $data = \app\common\model\ChatTemp::with(['toUser','group','groupMembers','circle'])
        ->where([
            'user_id'=>$this->userId,
            'to_id'=>$params['to_id'],
        ])
        ->find();
        return show(config('status.success'),'临时消息详情',$data);
    }

    /**
     * 我的聊天列表
     */
    public function chatList()
    {
        $enable = [
            'private_status'  => \app\common\service\ConfigService::get('chat', 'private_status',0),
            'group_status'  =>  \app\common\service\ConfigService::get('chat', 'group_status',0),
            'circle_status'  =>  \app\common\service\ConfigService::get('chat', 'circle_status',0),
        ];

        
        $types = [];

        foreach($enable as $k=>$v){
            switch($k){
                case 'private_status':
                    if($v == 1)$types[]='private_chat';
                    break;
                case 'group_status':
                    if($v == 1)$types[]='group_chat';
                    break;
                case 'circle_status':
                    if($v == 1)$types[]='group_chat';
                    break;
            }
        }
        
        $list = \app\common\model\ChatTemp::with(['toUser','group','groupMembers','circle'])
        ->where('type','in',$types)
        ->where('user_id',$this->userId)
        ->order(['update_time'=>'desc'])
        ->paginate(10)
        ->toArray();

        // dd($list);

        foreach($list['data'] as &$v){

            if($v['type']=='private_chat'){

                if (!isset($v['toUser']['id'])) {
                    continue;
                }
                
                // 在线
                $v['online']=checkOnline($v['toUser']['id']);

                $v['new_message'] = null;
                // from_user 发送者的信息
                $newMsg = \app\common\model\ChatPrivateMessage::with(['from_user','transfers'])
                ->whereOr([
                            // 我发除去的消息
                            [
                                ['from_id','=',$this->userId],
                                ['to_id','=',$v['to_id']]
                            ],
                            // 我接收过来的消息
                            [
                                ['from_id','=',$v['to_id']],
                                ['to_id','=',$this->userId]
                            ]
                        ])
                        ->order('id','desc')
                        ->find();
                        
                if($newMsg){
                    $v['new_message'] = $newMsg->toArray();
                }
            }elseif($v['type']=='group_chat'){
                $newMsg = \app\common\model\ChatGroupMessage::with(['from_user'])
                ->where('group_id',$v['group_id'])
                        ->order('id','desc')
                        ->find();
                if($newMsg){
                    $v['new_message'] = $newMsg->toArray();
                }
            }elseif($v['type']=='circle_chat'){
                $newMsg = \app\common\model\ChatCircleMessage::where('circle_id',$v['circle_id'])
                        ->order('id','desc')
                        ->find();
                if($newMsg){
                    $v['new_message'] = $newMsg->toArray();
                }
            }elseif($v['type']=='kefu_chat'){
                $newMsg = \app\common\model\ChatKefuMessage::where([
                    'user_id'=>$this->userId,
                    'kefu_id'=>$v['to_id'],
                ])
                        ->order('id','desc')
                        ->find();
                if($newMsg){
                    $v['new_message'] = $newMsg->toArray();
                }
            }
        }
        $list['unread']=\app\common\model\ChatTemp::where('user_id',$this->userId)->sum('unread');
        return $this->success('',$list);
    }

    public function groupDetail()
    {
        $group_id = $this->request->get('group_id');
        $data = \app\common\model\ChatGroup::with(['member'])->where('id',$group_id)->find()->toArray();
        $data['user_count'] = \app\common\model\ChatGroupMember::where('group_id',$group_id)->count();
        return $this->success('ok',$data,0);
    }

    /**
     * 删除聊天列表
     */
    public function delChat()
    {
        $id = $this->request->get('id');
        $res = \app\common\model\ChatTemp::destroy(['id'=>$id]);

        if($res){
            return $this->success('ok');
        }
        return $this->success('ok',[],0);
    }

    // 我加入的群列表
    public function groupList()
    {
        $list = \app\common\model\ChatGroupMember::where('user_id',$this->userId)
        ->where('status',1)
        ->with(['group','groupMembers'])
        ->select();
        return $this->success('ok',$list->toArray());
    }

    // 群成员列表
    public function groupMember()
    {
        $group_id = $this->request->get('group_id');
        $group_res = \app\common\model\ChatGroupMember::where([
            ['group_id','=',$group_id]
        ])
        ->find();
        if(!$group_res){
            return $this->success('无权限',[],0);
        }

        $online_count = 0;
        
        $list = \app\common\model\ChatGroupMember::with('user')
        ->where('group_id',$group_id)
        ->where('status',1)
        ->order('id','asc')
        ->select()
        ->toArray();

        // 在线情况判断
        foreach($list as &$v){
            $v['online']=checkOnline($v['user_id']);
            if($v['online']['status'] == 1){
                $online_count+=1;
            }
        }

        $data = [
            'online_count'=>$online_count,
            'list'=>$list,
        ];
        
        return $this->success('',$data);
        
    }

    /**
     * 新建群聊
     */
    // public function createGroup()
    // {
    //     Db::startTrans(); 
    //     try{
    //         $params = $this->request->post();
    //         $res = \app\common\model\ChatGroup::create([
    //             'create_by_user_id'=>$this->userId,
    //             'name'=>$params['name'],
    //             'desc'=>$params['desc'],
    //         ]);
    //         if(!$res){
    //             return $this->success('error',[],0);
    //         };
    //         \app\common\model\ChatGroupMember::create([
    //             'user_id'=>$this->userId,
    //             'group_id'=>$res->id,
    //         ]);
    //         Db::commit();
    //         return $this->success('ok',['group_id'=>$res->id]);
    //     }catch(\Exception $e){
    //         Db::rollback();
    //         return show(config('status.error'),'创建失败');
    //     }
    // }



    /**
     * 退出群聊
     */
    public function outGroup()
    {
        
        $params = $this->request->post();
        $res = Db::transaction(function() use ($params){
            $res = \app\common\model\ChatGroupMember::where([
                ['group_id','=',$params['group_id']],
                ['user_id','=',$this->userId]
            ])
            ->update([
                'status'=>0,
            ]);
            \app\common\model\ChatTemp::where([
                ['group_id','=',$params['group_id']],
                ['user_id','=',$this->userId]
            ])->delete();
            return $res;
        });
        
        
        if($res){
            return $this->success('ok');
        }else{
            return $this->success('error',[],0);
        };
    }

    /**
     * 进群
    */
    public function intoGroup()
    {
        $params = $this->request->get();
        $res = \app\common\model\ChatGroupMember::create([
            'user_id'=>$this->userId,
            'group_id'=>$params['group'],
        ]);
        if($res){
            return $this->success('ok');
        }else{
            return $this->success('error',[],0);
        };
    }

    /**
     * 群主拉人进群
     */
    // public function pullIntoGroup()
    // {
    //     $group_id = $this->request->post('group_id');
    //     $user_ids = $this->request->post('user_ids');
    //     $user_ids = explode(',',$user_ids);

    //     // 未再群里不让拉人
    //     $group_res = \app\common\model\ChatGroupMember::where([
    //         ['user_id','=',$this->userId],
    //         ['status','=',1],
    //         ['group_id','=',$group_id]
    //     ])
    //     ->find();
    //     if(!$group_res){
    //         return $this->success('无权限',[],0);
    //     }



    //     foreach($user_ids as $uid){
    //         if(empty($uid)){
    //             continue;
    //         }
    //         $res = \app\common\model\ChatGroupMember::create([
    //             'group_id'=>$group_id,
    //             'user_id'=>$uid,
    //         ]);
    //     }
        
    //     if($res){
    //         return $this->success('ok');
    //     }else{
    //         return $this->success('error',[],0);
    //     };
    // }

    /**
     * 修改群名和简介
     */
    public function groupUpdate()
    {
        $params = $this->request->post();

        $group_res = \app\common\model\ChatGroup::where('create_by_user_id',$this->userId)
        ->where('id',$params['group_id'])->find();
        if(!$group_res){
            return $this->success('无权限',[],0);
        }

        if(isset($params['name'])){
            $update_data['name']=$params['name'];
        }

        if(isset($params['desc'])){
            $update_data['desc']=$params['desc'];
        }
        // echo '<pre>';
        // print_r($update_data);

        $res = \app\common\model\ChatGroup::update($update_data,['id'=>$params['group_id']]);
        // dd($res->toArray());

        if($res){
            return $this->success('ok');
        }else{
            return $this->success('error',[],0);
        };
    }

    /**
     * @notes 聊天配置
     * @return \think\response\Json
     * @date 2022/3/14 15:01
     */
    public function chatConfig()
    {
        $result = CommonChatLogic::getConfig();
        return $this->success($result['msg'], [], $result['code']);
    }
    

    /**
     * 消息撤回
     */
    public function withdraw()
    {
        $params = $this->request->post();
        $where = [
            ['id','=',$params['id']],
            ['from_id','=',$this->userId],
        ];
        if($params['type'] == 'private'){//私聊
            $data = \app\common\model\ChatPrivateMessage::where($where)->find();
        }elseif($params['type'] == 'group'){//群聊
            $data = \app\common\model\ChatGroupMessage::where($where)->find();
        }elseif($params['type'] == 'circle'){//圈子聊
            $data = \app\common\model\ChatCircleMessage::where($where)->find();
        }

        if(!$data){
            return show(config('status.success'),'无权限');
        }

        if(time() - strtotime($data->create_time) > 60){
            return show(config('status.error'),'超过1分钟不支持撤回');
        }
        
        $data->status = 2;

        if (false === $data->save()) {
            return show(config('status.error'),$data->getError());
        }

        return show(config('status.success'),'撤回成功');
    }


}