<?php
/**
 * 微吼直播消息通知记录表 (防止重复推送)
 */

namespace Common\Service;

use Common\Common\Constant;
use Common\Common\Department;
use Common\Model\VhallModel;
use Common\Model\VhMsgLogModel;
use VcySDK\Cron;
use Common\Common\Msg;
use VcySDK\Service;
use VcySDK\Member;
use Common\Common\Tag;
use Common\Common\User;

class VhMsgLogService extends AbstractService
{


    public $_vh_main = null;

    // 构造方法
    public function __construct()
    {
        $this->_d = new VhMsgLogModel();
        $this->_vh_main = new VhallModel();

        parent::__construct();
    }

    /**
     * 获取目标范围内没有发送过消息的 uids
     * @param int $lmId
     * @param array $rangeUids 范围对象内的人员 ID
     * @param bool $rangeIsAll 如果范围是全公司
     * @return array
     */
    public function sendMsgRangeDiffUids($lmId, $rangeUids, $rangeIsAll = false)
    {

        // 获取历史消息推送记录
        $msgLogList = [];

        if (!empty($lmId)) {
            $msgLogConds = ['vh_id' => $lmId, 'type' => VhMsgLogModel::TYPE_LIVE_PUSH];
            $msgLogList = $this->_d->list_by_conds($msgLogConds);
        }

        if (!empty($msgLogList)) {
            // 有全公司 不用再发消息了
            if (in_array(Constant::RANGE_TYPE_ALL, array_column($msgLogList, 'obj_id'))) {
                return [];
            }

            // 去掉已经发过的
            foreach ($msgLogList as $item) {
                $uids = explode(',', $item['obj_id']);
                $rangeUids = array_diff($rangeUids, $uids);
            }
        }

        // 写入数据库
        if (!empty($rangeUids)) {
            // 如果是全公司
            if ($rangeIsAll) {
                $this->insert([
                    'vh_id' => $lmId,
                    'obj_id' => Constant::RANGE_TYPE_ALL,
                    'type' => VhMsgLogModel::TYPE_LIVE_PUSH
                ]);
            } else {
                $insertLog = [];
                foreach (array_chunk($rangeUids, Constant::OBJ_ID_SINGLE_TOTAL) as $item) {
                    $insertLog[] = [
                        'vh_id' => $lmId,
                        'obj_id' => implode(',', $item),
                        'type' => VhMsgLogModel::TYPE_LIVE_PUSH
                    ];
                }
                $this->insert_all($insertLog);
            }
        }

        return $rangeUids;
    }

    /**
     * 创建计划任务并保存
     * @param $lmId
     * @param $remark
     * @param $type
     * @param $time
     * @return bool
     */
    public function createCron($lmId, $remark, $type, $time)
    {
        $cronSdk = new Cron(Service::instance());

        // 建立 Job 发送消息
        $cronResult = $cronSdk->add([
            'crRemark' => $remark,
            'crType' => Cron::CR_TYPE_CALLBACK,
            'crParams' => json_encode([
                'lm_id' => $lmId,
                'type' => $type,
            ]),
            'crMethod' => 'POST',
            // 回调地址
            'crReqUrl' => oaUrl('Frontend/Callback/PushVhMsg/Index'),
            'crTimes' => 1,
            'crCron' => rgmdate((String)$time, 's i G j n ? Y'),
            'crMonitorExecution' => $cronSdk::CR_MONITOR_EXECUTION_FALSE,
            'crDescription' => '直播开始时推送消息提醒',
        ]);
        if (empty($cronResult['crId'])) {
            E(L('_ERR_CRON_OPTION_FAILED', ['option' => '创建']));
        }

        // 开始前提醒
        if (Constant::TYPE_LIVE_WILL_START == $type) {
            $data['notice_will_start_cron_id'] = $cronResult['crId'];
        }

        // 开始时提醒
        if (Constant::TYPE_LIVE_START == $type) {
            $data['notice_notice_start_cron_id'] = $cronResult['crId'];
        }

        $this->_vh_main->update_by_conds(['vh_id' => $lmId], $data);

        return true;
    }


    /**
     * 即时消息通知方法 【发消息统一写这里,方便维护】
     * @param $params -通知参数
     *          + uids      -用户uid数组
     *              + memID     -用户uid
     *          + dp_ids    -部门id数组
     *              + dpID      -部门id
     *          + tag_ids   -标签id数组
     *              + tagID     -标签id
     *          + job_ids   -岗位id数组
     *              + jobID     -岗位id
     *          + role_ids  -角色id数组
     *              + roleID    -角色id
     *          + lm_id     -直播ID
     *          + name      -直播标题
     *          + start_time    -直播开始时间
     *          + estimated_duration    -直播预计时长
     *          + desc      -直播摘要
     * @param $type -通知文案类型
     * @return bool
     */
    public function send_vh_Msg($params, $type)
    {
        // 获取应用名称
        $application_name = cfg('APPLICATION_NAME');

        // 过滤内容中的空格标签
        $search = ["&nbsp;", "&nbsp"];
        $replace = [" ", " "];
        $content = str_replace($search, $replace, strip_tags($params['liveDesc']));

        // 开始时间
        $rgmDate = rgmdate($params['liveStartTime'], 'Y-m-d H:i');

        // 本方法根据类型区分拼接不通的文案
        switch ($type) {

            case self::MSG_LIVE_PUBLISH:
                $data = [
                    'title' => '【' . cfg('APPLICATION_NAME') . '】有新的直播活动发布,快来观看吧!',
                    'description' => "标题:{$params['liveName']}\r\n开始时间:{$rgmDate}\r\n预计时长:{$params['liveTimeLength']}分钟\r\n主讲人:{$params['teacher_name']}\r\n直播简介:" . $this->cutstr($content, 0, 20) . "\r\n主讲人简介:{$params['teacher_desc']}",
                    'picUrl' => '',
                ];
                break;
            case self::MSG_REMAIND_NO_JOIN_USERS:

                $data = [
                    'title' => '【' . $application_name . '】您有一个直播未观看,快去瞧瞧吧!',
                    'description' => "标题:{$params['liveName']}\r\n开始时间:{$rgmDate}\r\n预计时长:{$params['liveTimeLength']}分钟\r\n主讲人:{$params['teacher_name']}\r\n直播简介:" . $this->cutstr($content, 0, 20) . "\r\n主讲人简介:{$params['teacher_desc']}",
                    'picUrl' => '',
                ];
                break;
            case self::MSG_LIVE_WILL_START:
                $data = [
                    'title' => '【' . $application_name . '】直播活动仅剩' . $params['notice_will_start'] . '分钟开始,快来观看吧!',
                    'description' => "标题:{$params['liveName']}\r\n开始时间:{$rgmDate}\r\n预计时长:{$params['liveTimeLength']}分钟\r\n主讲人:{$params['teacher_name']}\r\n直播简介:" . $this->cutstr($content, 0, 20) . "\r\n主讲人简介:{$params['teacher_desc']}",
                    'picUrl' => '',
                ];
                break;
            case self::MSG_LIVE_START:
                $data = [
                    'title' => '【' . $application_name . '】直播活动已经开始,快来观看吧!',
                    'description' => "标题:{$params['liveName']}\r\n开始时间:{$rgmDate}\r\n预计时长:{$params['liveTimeLength']}分钟\r\n主讲人:{$params['teacher_name']}\r\n直播简介:" . $this->cutstr($content, 0, 20) . "\r\n主讲人简介:{$params['teacher_desc']}",
                    'picUrl' => '',
                ];
                break;
            case self::MSG_LECTURER_APPOINTMENT:
                // 直播地址
                $pushUrl = (is_ssl() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] .
                    '/admincp/#/live-pc?liveId=' . $params['id'].'&epId='.$params['epId'];
                // 跳转地址 (send 方法内用到)
                $params['jumpUrl'] = oaUrl('Frontend/Index/VhLive/guide', ['liveId' => $params['id']]);

                $data = [
                    'title' => '【' . $application_name . '】您已被设置为直播讲师,请做好准备!',
                    'description' => "标题:{$params['liveName']}\r\n开始时间:{$rgmDate}\r\n直播口令:{$params['livePassword']}\r\n直播地址:" . $pushUrl,
                    'picUrl' => '',
                ];
                break;
            default:

                return true;
        }

        $this->send_vh($params, $data);

        return true;
    }

    private function send_vh($params = [], $condition = [])
    {
        // 发送消息接收人
        $msgUser = !empty($params['liveScopeUsers']) ? $params['liveScopeUsers'] : [];
        $toUser = isset($params['liveScopeAll']) && !empty($params['liveScopeAll']) ? '@all' : $msgUser;

        // 发送消息部门
        $toParty = !empty($params['liveScopeDepts']) ? $params['liveScopeDepts'] : [];

        // 角色或者岗位发送消息
        if (!empty($params['liveScopeJobs']) || !empty($params['liveScopeRoles'] || !empty($params['liveScopeTags']))) {

            // 获取权限下的uids
            $uids = $this->get_auth_uids($params);

            // 如果权限里有人员并且选择的不是全公司
            if (!empty($uids) && empty($params['liveScopeAll'])) {

                $toUser = array_merge($toUser, $uids);

                // 去重复人员
                $toUser = array_unique($toUser);
            }
        }

        // 如果用户和部门为空则不发消息
        if (empty($toUser) && empty($toParty)) {

            return true;
        }

        $articles = array(
            array(
                'title' => $condition['title'],
                'description' => $condition['description'],
                'url' =>
                    !isset($params['jumpUrl']) ?
                        oaUrl('Frontend/Index/VhLive/room', array('liveId' => $params['id'], 'liveVhallId' => $params['liveVhallId'])) :
                        $params['jumpUrl'],
                'picUrl' => '',
            ),
        );

        try {
            $msgServ = &Msg::instance();
            $msgServ->sendNews($toUser, $toParty, '', $articles);

        } catch (\Exception $e) {

            \Think\Log::record('发送消息失败:::' . var_export($e, true));
            E($e->getCode() . ':' . $e->getMessage());
        }

        return true;
    }

    /**
     * 通过岗位角色标签人员部门信息获取
     * @param array $params
     * @return array
     */
    public function get_auth_uids($params = [])
    {

        $uids = $params['liveScopeUsers'] ? $params['liveScopeUsers'] : [];
        if (is_json($params['liveScopeUsers']) && !is_array($params['liveScopeUsers'])) {
            $uids = json_decode($params['liveScopeUsers'], true);
        }

        // 初始化标签下的部门
        $tag_dp_id = [];

        $user = User::instance();
        // 处理岗位
        if (!empty($params['liveScopeJobs'])) {

            if (is_json($params['liveScopeJobs']) && !is_array($params['liveScopeJobs'])) {
                $params['liveScopeJobs'] = json_decode($params['liveScopeJobs'], true);
            }

            $params['liveScopeJobs'] = array_unique($params['liveScopeJobs']);
            sort($params['liveScopeJobs']);

            // 获取岗位列表
            $job_list = $user->listAll(array('jobIdList' => $params['liveScopeJobs']));

            // 如果岗位下存在人员
            if (!empty($job_list)) {
                $uids = array_column($job_list, 'memUid');
            }
        }

        // 处理角色
        if (!empty($params['liveScopeRoles'])) {

            if (is_json($params['liveScopeRoles']) && !is_array($params['liveScopeRoles'])) {
                $params['liveScopeRoles'] = json_decode($params['liveScopeRoles'], true);
            }

            $params['liveScopeRoles'] = array_unique($params['liveScopeRoles']);

            sort($params['liveScopeRoles']);

            // 获取角色列表
            $role_List = $user->listAll(array('roleIdList' => $params['liveScopeRoles']));

            // 如果岗位下存在人员
            if (!empty($role_List)) {

                $uids = array_merge($uids, array_column($role_List, 'memUid'));
            }

        }

        // 处理标签
        if (!empty($params['liveScopeTags'])) {

            if (is_json($params['liveScopeTags']) && !is_array($params['liveScopeTags'])) {
                $params['liveScopeTags'] = json_decode($params['liveScopeTags'], true);
            }

            $params['liveScopeTags'] = array_unique($params['liveScopeTags']);

            sort($params['liveScopeTags']);

            $tag = new Tag();
            $tag_List = $tag->listUserByTagId($params['liveScopeTags'], 1, 1000);

            // 如果标签下存在人员
            if (!empty($tag_List['list'])) {

                $uids = array_merge($uids, array_column($tag_List['list'], 'memUid'));
            }

            $tag_dp_id = array_filter(array_column($tag_List['list'], 'dpId'));

            $tag_dp_id = (array)$tag_dp_id;

        }

        // 处理部门
        if (!empty($params['liveScopeDepts']) || !empty($tag_dp_id)) {

            // 获取标签下的部门
            if (is_json($params['liveScopeDepts'])&& !is_array($params['liveScopeDepts'])) {
                $params['liveScopeDepts'] = json_decode($params['liveScopeDepts'], true);
            }

            // 合并标签下的部门ID集合
            $params['liveScopeDepts'] = array_merge((array) $params['liveScopeDepts'], $tag_dp_id);

            $params['liveScopeDepts'] = array_unique($params['liveScopeDepts']);

            sort($params['liveScopeDepts']);

            $dp_conds = ['dpIdList' => $params['liveScopeDepts'], 'departmentChildrenFlag' => 1];

            $dp_users = $user->listAll($dp_conds);

            if (!empty($dp_users)) {
                // 部门下的员工id集合
                $d_uids = array_column($dp_users, 'memUid');
                $uids = array_merge($uids, $d_uids);
            }

        }
        $uids = array_unique(array_filter($uids));
        return $uids;
    }

    /***
     * 赋值导师id
     * 去除权限数据
     * 发送消息
     * @param array $params
     * @param $type
     * @return bool
     */
    public function send_teacher_msg($params = [], $type)
    {
        $uid = $params['teacher_id'];

        foreach (Constant::VH_SCOPE_SETTING_FIELD as $item) {
            unset($params[$item]);
        }

        $params['liveScopeUsers'] = $uid;
        $this->send_vh_Msg($params, $type);
        return true;
    }
}