package com.ym.mec.biz.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.biz.dal.dao.ImLiveRoomReservationDao;
import com.ym.mec.biz.dal.entity.ImLiveBroadcastRoom;
import com.ym.mec.biz.dal.entity.ImLiveRoomReservation;
import com.ym.mec.biz.dal.entity.Student;
import com.ym.mec.biz.dal.enums.MessageTypeEnum;
import com.ym.mec.biz.dal.vo.ImLiveBroadcastRoomVo;
import com.ym.mec.biz.service.ImLiveRoomReservationService;
import com.ym.mec.biz.service.StudentService;
import com.ym.mec.biz.service.SysMessageService;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.page.PageInfo;
import com.ym.mec.common.page.PageUtil;
import com.ym.mec.common.tenant.TenantContextHolder;
import com.ym.mec.thirdparty.message.MessageSenderPluginContext;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 直播预约记录(ImLiveRoomReservation)表服务实现类
 *
 * @author hgw
 * @since 2022-05-24 14:54:13
 */
@Service("imLiveRoomReservationService")
public class ImLiveRoomReservationServiceImpl extends ServiceImpl<ImLiveRoomReservationDao, ImLiveRoomReservation> implements ImLiveRoomReservationService {

    private final static Logger log = LoggerFactory.getLogger(ImLiveRoomReservationServiceImpl.class);

    @Autowired
    private SysUserFeignService sysUserFeignService;
    @Autowired
    private StudentService studentService;
    @Autowired
    private SysMessageService sysMessageService;

    /**
     * 预约直播
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(ImLiveRoomReservation entity) {
        Optional<ImLiveRoomReservation> optional = Optional.ofNullable(entity);
        optional.filter(a -> StringUtils.isNotBlank(a.getRoomUid())).orElseThrow(() -> new BizException("房间Uid不能为空"));
        optional.filter(a -> Objects.nonNull(a.getUserId())).orElseThrow(() -> new BizException("学员id不能为空"));
        entity.setPushState(-1);
        entity.setCreateTime(new Date());
        this.saveOrUpdate(entity);
    }

    /**
     * 取消预约
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void cancel(ImLiveRoomReservation entity) {
        this.remove(Wrappers.<ImLiveRoomReservation>lambdaUpdate()
                .eq(ImLiveRoomReservation::getRoomUid, entity.getRoomUid())
                .eq(ImLiveRoomReservation::getUserId, entity.getUserId()));
    }

    /**
     * 分页查询直播间
     *
     * @param param 参数
     *              <p> liveState 直播状态 0未开始 1开始 2结束
     */
    @Override
    public PageInfo<ImLiveBroadcastRoomVo> queryPageStudent(Map<String, Object> param) {
        SysUser user = getUser();
        Page<ImLiveBroadcastRoomVo> pageInfo = PageUtil.concatTimePage(param, "startTime", "endTime");
        pageInfo.setDesc("a.created_time_");
        param.put("userId", user.getId());
        param.put("tenantId", TenantContextHolder.getTenantId());
        return PageUtil.pageInfo(baseMapper.queryPageStudent(pageInfo, param));
    }

    /**
     * 预约直播间推送极光
     */
    @Override
    public void push(ImLiveBroadcastRoom room) {
        List<ImLiveRoomReservation> list = this.list(Wrappers.<ImLiveRoomReservation>lambdaQuery()
                .eq(ImLiveRoomReservation::getRoomUid, room.getRoomUid())
                .eq(ImLiveRoomReservation::getPushState, -1));
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        SysUser user = getUser(room.getSpeakerId());
        String memo = "10?roomUid=" + room.getRoomUid();
        Map<Integer, String> pushStudentList = new HashMap<>();
        for (ImLiveRoomReservation obj : list) {
            pushStudentList.put(obj.getUserId(), obj.getUserId().toString());
        }
        //推送状态
        AtomicInteger pushState = new AtomicInteger(0);
        try {
            // 约直播间通知发送
            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.JIGUANG_LIVE_RESERVATION, pushStudentList,
                    null, 0, memo, "STUDENT", user.getUsername(), room.getRoomTitle());
        } catch (Exception e) {
            log.error("推送消息失败", e);
            pushState.set(1);
        }
        log.info("ImLiveRoomReservation push >>> state:{}  |>>>> memo:{} |>>>> studentList :{} |>>>> username:{}  |>>>>room:{}", pushState.get(), memo, pushStudentList, user.getUsername(), JSONObject.toJSONString(room));
        //修改推送状态
        this.update(Wrappers.<ImLiveRoomReservation>lambdaUpdate()
                .set(ImLiveRoomReservation::getPushState, pushState.get())
                .eq(ImLiveRoomReservation::getRoomUid, room.getRoomUid()));
    }

    @Override
    public List<ImLiveBroadcastRoomVo> countRoomReservation(List<String> roomIdList) {
        return baseMapper.selectCountRoomReservation(roomIdList);
    }

    private SysUser getUser() {
        return Optional.ofNullable(sysUserFeignService.queryUserInfo())
                .orElseThrow(() -> new BizException("用户信息获取失败,请刷新页面或者重新登录!"));
    }

    private SysUser getUser(Integer userId) {
        return Optional.ofNullable(userId)
                .map(sysUserFeignService::queryUserById)
                .orElseThrow(() -> new BizException("用户不存在"));
    }

}

