package com.fs.live.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.thread.ThreadUtil;
import com.alibaba.fastjson.JSON;
import com.fs.common.constant.LiveKeysConstant;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.core.redis.RedisUtil;
import com.fs.common.utils.DateUtils;
import com.fs.live.domain.Live;
import com.fs.live.domain.LiveWatchUser;
import com.fs.live.mapper.LiveWatchUserMapper;
import com.fs.live.service.ILiveWatchUserService;
import com.fs.live.vo.LiveWatchUserVO;
import com.fs.store.domain.FsUser;
import com.fs.store.service.IFsUserService;
import com.fs.store.vo.FsUserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 直播间观看用户Service业务层处理
 *
 * @author fs
 * @date 2025-01-18
 */
@Service
@Slf4j
public class LiveWatchUserServiceImpl implements ILiveWatchUserService {

    @Autowired
    private RedisCache redisCache;
    @Autowired
    private IFsUserService fsUserService;
    @Autowired
    private LiveWatchUserMapper baseMapper;

    @Autowired
    private RedisUtil redisUtil;
    /**
     * 查询直播间观看用户
     *
     * @param id 直播间观看用户主键
     * @return 直播间观看用户
     */
    @Override
    public LiveWatchUser selectLiveWatchUserById(Long id)
    {
        return baseMapper.selectLiveWatchUserById(id);
    }

    /**
     * 查询企业直播间观看用户
     * @param id                直播间用户ID
     * @param companyId         企业ID
     * @param companyUserId     企业用户ID
     * @return LiveWatchUser
     */
    @Override
    public LiveWatchUser selectLiveWatchUserByIdAndCompanyIdAndCompanyUserId(Long id, Long companyId, Long companyUserId)
    {
        return baseMapper.selectLiveWatchUserByIdAndCompanyIdAndCompanyUserId(id, companyId, companyUserId);
    }

    /**
     * 查询直播间观看用户列表
     *
     * @param liveWatchUser 直播间观看用户
     * @return 直播间观看用户
     */
    @Override
    public List<LiveWatchUser> selectLiveWatchUserList(LiveWatchUser liveWatchUser)
    {
        return baseMapper.selectLiveWatchUserList(liveWatchUser);
    }

    /**
     * 新增直播间观看用户
     *
     * @param liveWatchUser 直播间观看用户
     * @return 结果
     */
    @Override
    public int insertLiveWatchUser(LiveWatchUser liveWatchUser)
    {
        liveWatchUser.setCreateTime(DateUtils.getNowDate());
        return baseMapper.insertLiveWatchUser(liveWatchUser);
    }

    /**
     * 修改直播间观看用户
     *
     * @param liveWatchUser 直播间观看用户
     * @return 结果
     */
    @Override
    public int updateLiveWatchUser(LiveWatchUser liveWatchUser)
    {
        liveWatchUser.setUpdateTime(DateUtils.getNowDate());
        return baseMapper.updateLiveWatchUser(liveWatchUser);
    }

    /**
     * 批量删除直播间观看用户
     *
     * @param ids 需要删除的直播间观看用户主键
     * @return 结果
     */
    @Override
    public int deleteLiveWatchUserByIds(Long[] ids)
    {
        return baseMapper.deleteLiveWatchUserByIds(ids);
    }

    /**
     * 删除直播间观看用户信息
     *
     * @param id 直播间观看用户主键
     * @return 结果
     */
    @Override
    public int deleteLiveWatchUserById(Long id)
    {
        return baseMapper.deleteLiveWatchUserById(id);
    }

    @Override
    public LiveWatchUser getByLiveIdAndUserId(long liveId, long userId) {
        return baseMapper.selectUserByLiveIdAndUserId(liveId, userId);
    }

    @Override
    public LiveWatchUser join(long liveId, long userId) {
        LiveWatchUser liveWatchUser = getByLiveIdAndUserId(liveId, userId);
        FsUserVO fsUserVO = fsUserService.selectFsUserByUserId(userId);
        if(liveWatchUser != null) {
            liveWatchUser.setUpdateTime(DateUtils.getNowDate());
            liveWatchUser.setOnline(0);
            baseMapper.updateLiveWatchUser(liveWatchUser);
        }else{
            liveWatchUser = new LiveWatchUser();
            liveWatchUser.setLiveId(liveId);
            liveWatchUser.setUserId(userId);
            liveWatchUser.setAvatar(fsUserVO.getAvatar());
            liveWatchUser.setMsgStatus(0);
            liveWatchUser.setOnline(0);
            liveWatchUser.setCreateTime(DateUtils.getNowDate());
            liveWatchUser.setUpdateTime(DateUtils.getNowDate());
            baseMapper.insertLiveWatchUser(liveWatchUser);
        }
        liveWatchUser.setAvatar(fsUserVO.getAvatar());
        liveWatchUser.setNickName(fsUserVO.getNickname());
        String hashKey  = String.format(LiveKeysConstant.LIVE_WATCH_USERS, liveId);
        redisUtil.hashPut(hashKey, String.valueOf(userId), JSON.toJSONString(liveWatchUser));
        return liveWatchUser;
    }
    @Override
    public LiveWatchUser close(long liveId, long userId) {
        LiveWatchUser liveWatchUser = getByLiveIdAndUserId(liveId, userId);
        liveWatchUser.setUpdateTime(DateUtils.getNowDate());
        liveWatchUser.setOnline(1);
        baseMapper.updateLiveWatchUser(liveWatchUser);
        String hashKey  = String.format(LiveKeysConstant.LIVE_WATCH_USERS, liveId);
        redisUtil.hashDelete(hashKey, String.valueOf(userId));
        return liveWatchUser;
    }

    /**
     * 查询直播间在线用户列表
     * @param params 参数
     * @return list
     */
    @Override
    public List<LiveWatchUserVO> selectWatchUserList(Map<String, Object> params) {
        return baseMapper.selectWatchUserListByLiveId(params);
    }

    /**
     * 修改直播间用户禁言状态
     * @param liveId    直播间ID
     * @param userId    用户ID
     * @return  受影响条数
     */
    @Override
    public int changeUserState(Long liveId, Long userId) {
        LiveWatchUser liveWatchUser = getByLiveIdAndUserId(liveId, userId);
        if (Objects.nonNull(liveWatchUser)) {
            liveWatchUser.setMsgStatus(Math.abs(1 - liveWatchUser.getMsgStatus()));
            liveWatchUser.setUpdateTime(DateUtils.getNowDate());
            return baseMapper.updateLiveWatchUser(liveWatchUser);
        }
        return 0;
    }

    /**
     * 根据直播间ID和用户ID查询观看用户信息
     * @param liveId    直播间ID
     * @param userId    观看用户ID
     * @return LiveWatchUserVO
     */
    @Override
    public LiveWatchUserVO selectWatchUserByLiveIdAndUserId(Long liveId, Long userId) {
        return baseMapper.selectWatchUserByLiveIdAndUserId(liveId, userId);
    }

    @Override
    public List<LiveWatchUserVO> selectOnlineUserList(LiveWatchUser param) {
        return baseMapper.selectOnlineUserList(param);
    }

    @Override
    public List<LiveWatchUser> checkOnlineNoRewardUser(Long liveId, Date now) {
        return baseMapper.checkOnlineNoRewardUser(liveId,now);
    }

    @Override
    public int blockUser(Long userId) {
        FsUser fsUser = new FsUser();
        fsUser.setUserId(userId);
        fsUser.setStatus(0);
        return fsUserService.updateFsUser(fsUser);
    }

    @Override
    public List<LiveWatchUser> selectLiveWatchAndRegisterUser(Long liveId, Long lotteryId,Integer totalLots) {
        return baseMapper.selectLiveWatchAndRegisterUser(liveId, lotteryId,totalLots);
    }

    @Override
    public List<LiveWatchUserVO> asyncToCache(Long liveId) {
        LiveWatchUser liveWatchUser = new LiveWatchUser();
        liveWatchUser.setLiveId(liveId);
        List<LiveWatchUserVO> liveWatchUserVOS = selectOnlineUserList(liveWatchUser);

        log.info("开始同步直播在线人数到缓存，共{}条数据", liveWatchUserVOS.size());
        if (CollUtil.isNotEmpty(liveWatchUserVOS)){
            ThreadUtil.execute(()->{
                String hashKey  = String.format(LiveKeysConstant.LIVE_WATCH_USERS, liveId);
                // 清空数据
                redisUtil.delete(hashKey);
                Map<String, String> collect = liveWatchUserVOS.stream()
                        .collect(Collectors.toMap(
                                watchUserVO -> String.valueOf(watchUserVO.getUserId()),
                                JSON::toJSONString
                        ));
                redisUtil.hashPut(hashKey,collect);
                log.info("同步直播在线人数到缓存完成");
            });
        }
        return liveWatchUserVOS;
    }

}
