<?php
namespace app\admin\command;

use think\console\Command;
use think\console\Input;
use think\console\Output;
use app\admin\model\User;
use app\admin\model\Config;
use app\admin\model\KefuTime;
use app\admin\model\KefuLog;
use think\facade\Db;
use GatewayClient\Gateway;

/**
 * Worker 命令行类
 */
class UserTimeout extends Command
{
    public function configure()
    {
        $this->setName('user:timeout')
            ->setDescription('用户会话检测');
    }

    public function execute(Input $input, Output $output)
    {

        //检测离线用户状态
        $this->checkOfflineUser();


        $config = Config::whereIn('field',['kefu_timeout_reminder','kefu_timeout_warning','user_timeouted_warning', 'user_timeout_warning','user_inline_finished'])->column('val','field');
       
        $user_timeout_warning = 0;
        if (isset($config['user_timeout_warning']) && $config['user_timeout_warning'] > 0) {
            $user_timeout_warning = $config['user_timeout_warning'];
            //用户等待即将超时预警
            $list = User::where('status', 1)->where('is_online', 1)->where('service_status', 1)
                    ->where('service_start', '<=', time() - $user_timeout_warning)
                    ->where('timeout_type', 0)
                    ->select()
                    ->toArray();
            $this->sendMessage($list, 1);
            $output->writeln('用户等待即将超时预警：'.count($list));
        }

        if (isset($config['user_timeouted_warning']) && $config['user_timeouted_warning'] > 0) {
            $user_timeouted_warning = $config['user_timeouted_warning'];
            //用户等待已超时预警
            $list = User::where('status', 1)->where('is_online', 1)->where('service_status', 1)
                    ->where('service_start', '<=', time() - $user_timeouted_warning)
                    ->where(function($query) use ($user_timeout_warning){
                        if ($user_timeout_warning > 0) {
                            $query->where('service_start', '>', time() - $user_timeout_warning);
                        }
                    })
                    ->where('timeout_type', '<',2)
                    ->select()
                    ->toArray();
            $this->sendMessage($list, 2);
            $output->writeln('用户等待已超时预警'.count($list));
        }

        $kefu_timeout_warning = 0;
        if (isset($config['kefu_timeout_warning']) && $config['kefu_timeout_warning'] > 0) {
            $kefu_timeout_warning = $config['kefu_timeout_warning'];
            //用户服务中-即将超时预警时间
            $list = User::where('status', 1)->where('is_online', 1)->where('service_status', 2)
                    ->where('service_start', '<=', time() - $kefu_timeout_warning)
                    ->where('timeout_type', '<',3)
                    ->select()
                    ->toArray();
            $this->sendMessage($list, 3);
            $output->writeln('用户服务中-即将超时预警'.count($list));
        }

        if (isset($config['kefu_timeout_reminder']) && $config['kefu_timeout_reminder'] > 0) {
            $timeout_reminder = $config['kefu_timeout_reminder'];
            //用户服务中-已超时提醒
            $list = User::where('status', 1)->where('is_online', 1)->where('service_status', 2)
                    ->where('service_start', '<=', time() - $timeout_reminder)
                    ->where(function($query) use ($kefu_timeout_warning){
                        if ($kefu_timeout_warning > 0) {
                            $query->where('service_start', '<=', time() - $kefu_timeout_warning);
                        }
                    })
                    ->where('timeout_type', '<',4)
                    ->select()
                    ->toArray();
            $output->writeln('用户服务中-已超时提醒'.count($list));
            $this->sendMessage($list, 4);
        }

        if (isset($config['user_inline_finished']) && $config['user_inline_finished'] > 0) {
            $user_inline_finished = $config['user_inline_finished'] * 60;
            //会员离线后自动结束会话时间
            $list = User::where('role', 0)
                    ->where('is_online', 0)
                    ->whereIn('service_status', [0,1,2])
                    ->where('offline_time', '<=', time() - $user_inline_finished)
                    ->select()
                    ->toArray();
            $cs_uid = getAutoCsUid();//获取机器人ID
            foreach($list as $user) {
                try {
                    Db::startTrans();
                    //用户转给机器人客服
                    User::where('user_id', $user['user_id'])->update(['service_status' => -1, 'service_start' => 0, 'timeout_type' => 0, 'cs_uid'=>$cs_uid]);
                    KefuTime::endData($user['uid'], 3, $user['cs_uid']); //结束接线时间
                    //客服对接记录表
                    KefuLog::endData($user['cs_uid'], $user['user_id']);
                    //客服对接记录表
                    KefuLog::addData($cs_uid, $user['user_id'], 3);

                    Db::commit();
                    
                    //通知关闭聊天框
                    wsSendMsg($user['cs_uid'],'closeChat',['user_id'=>$user['user_id']]);

                    //通知客服已结束
                    wsSendMsg($user['cs_uid'],'handleChat',['user_id'=>$user['user_id']]);
                } catch (\Exception $e) {
                    Db::rollback();
                }
            }
            $output->writeln('会员离线后自动结束会话时间'.count($list));
        }
        
        if (isset($config['kefu_inline_finished']) && $config['kefu_inline_finished'] > 0) {
            $kefu_inline_finished = $config['kefu_inline_finished'] * 60;
            //客服离线后自动结束会话时间
            $list = User::where('role', 3)
                    ->where('is_online', 0)
                    ->where('is_finished', 0)
                    ->where('offline_time', '<=', time() - $kefu_inline_finished)
                    ->select()
                    ->toArray();
            $cs_uid = getAutoCsUid();//获取机器人ID
            foreach($list as $user) {
                try {
                    Db::startTrans();
                    
                    User::kefuOffline($user['user_id'], $user['uid']);

                    Db::commit();
                } catch (\Exception $e) {
                    Db::rollback();
                }
            }
            $output->writeln('客服离线后自动结束会话时间'.count($list));
        }
    }

    //检测离线用户，更新在线状态
    public function checkOfflineUser()
    {
        Gateway::$registerAddress = config('gateway.registerAddress');
        $onlineList=Gateway::getAllUidList();
        $userOnlineList = User::where('is_online', '>', 0)->column('user_id');
        
        foreach($userOnlineList as $user_id) {
            if(!isset($onlineList[$user_id])) {
                User::where('user_id', $user_id)->update(['is_online' => 0]);
            }
        }
    }

    /**
     * 发送提醒通知
     */
    public function sendMessage($list, $type)
    {
        foreach($list as $user) {
            //更新用户超时提醒的状态
            User::where('user_id', $user['user_id'])->update(['timeout_type' => $type]);
            //通知客服已结束
            wsSendMsg($user['cs_uid'],'timeout',['user_id'=>$user['user_id'], 'realname'=>$user['realname'], 'type'=>$type]);
        }
    }

}