package org.dromara.system.service.impl.info;

import com.google.api.client.util.SecurityUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.info.InfoPingLun;
import org.dromara.system.domain.info.XiaoyuanInfo;
import org.dromara.system.domain.info.bo.InfoPingLunBo;
import org.dromara.system.domain.info.vo.InfoPingLunVo;
import org.dromara.system.domain.info.vo.XiaoyuanInfoVo;
import org.dromara.system.domain.score.ScoreDataMf;
import org.dromara.system.mapper.info.InfoPingLunMapper;
import org.dromara.system.mapper.info.XiaoyuanInfoMapper;
import org.dromara.system.service.info.IXiaoyuanInfoService;
import org.springframework.stereotype.Service;
import org.dromara.system.domain.bo.XiaoyuanInfoBo;
import util.BadWordsUtil;

import java.util.*;
import java.util.stream.Collectors;

import static org.dromara.common.core.constant.CacheConstants.*;

/**
 * 校园安全信息Service业务层处理
 *
 * @author boman
 * @date 2023-08-16
 */
@RequiredArgsConstructor
@Service
public class XiaoyuanInfoServiceImpl implements IXiaoyuanInfoService {

    private final XiaoyuanInfoMapper baseMapper;
    private final InfoPingLunMapper infoPingLunMapper;

    /**
     * 查询校园安全信息
     */
    @Override
    public XiaoyuanInfoVo queryById(Long infoId){
        //已读数量+1
        XiaoyuanInfoVo xiaoyuanInfo = baseMapper.selectXiaoyuanInfoByInfoId(infoId);
        String infoYiDu = xiaoyuanInfo.getInfoYiDu();
        int result = Integer.parseInt(infoYiDu) + 1;
        xiaoyuanInfo.setInfoYiDu(String.valueOf(result));

        //组装评论
        List<InfoPingLunVo> infoPingLunList = xiaoyuanInfo.getInfoPingLunList();
        if (infoPingLunList != null && infoPingLunList.size() > 0){
            //根据评论类型进行分组评论类型 1:评论 2:回复
            Map<String, List<InfoPingLunVo>> collect = infoPingLunList.stream().sorted(Comparator.comparing(InfoPingLunVo::getPingLunTime, Comparator.reverseOrder())).collect(Collectors.groupingBy(InfoPingLunVo::getInfoPingLunType));
            if (collect != null && collect.size() > 0){
                //所有评论类型的数据
                List<InfoPingLunVo> infoPingLunListFather = collect.get("1");
                //给他们找自己的回复类型的数据
                if (infoPingLunListFather != null && infoPingLunListFather.size() > 0){
                    for (InfoPingLunVo infoPinglun : infoPingLunListFather) {
                        List<InfoPingLunVo> infoPinglunList = collect.get("2");
                        //回复不是空
                        if(infoPinglunList != null && infoPinglunList.size() > 0){
                            Map<Long, List<InfoPingLunVo>> infoPingLunListParen = infoPinglunList.stream().collect(Collectors.groupingBy(InfoPingLunVo::getInfoPingLunParent));
                            List<InfoPingLunVo> infoPinglunListCh = infoPingLunListParen.get(infoPinglun.getInfoPingLunId());
                            if (infoPinglunListCh != null && infoPinglunListCh.size() > 0){
                                infoPinglun.setInfoPingLunList(infoPinglunListCh.stream().sorted(Comparator.comparing(InfoPingLunVo::getPingLunTime, Comparator.reverseOrder())).collect(Collectors.toList()));
                            }
                        }
                    }
                }
                xiaoyuanInfo.setInfoPingLunList(infoPingLunListFather);
            }
        }
        //获取点赞/分享/这个人是否点赞信息
        Object dianZan = RedisUtils.getCacheObject(XIAOYUAN_INFO_DIANZAN + xiaoyuanInfo.getInfoId());
        if (ObjectUtils.isNotEmpty(dianZan)){
            xiaoyuanInfo.setInfoDianZan(String.valueOf(dianZan));
        }
        Object zhuanFa = RedisUtils.getCacheObject(XIAOYUAN_INFO_ZHUANFA+ xiaoyuanInfo.getInfoId());
        if (ObjectUtils.isNotEmpty(zhuanFa)){
            xiaoyuanInfo.setInfoZhuanFa(String.valueOf(zhuanFa));
        }
        Object dianZanUser = RedisUtils.getCacheObject(XIAOYUAN_INFO_DIANZAN_USER + xiaoyuanInfo.getInfoId());
        xiaoyuanInfo.setIsDianZan("N");
        if (ObjectUtils.isNotEmpty(dianZanUser)){
            xiaoyuanInfo.setIsDianZan("Y");
        }
        baseMapper.updateById(MapstructUtils.convert(xiaoyuanInfo, XiaoyuanInfo.class));
        return xiaoyuanInfo;
    }

    /**
     * 查询校园安全信息列表
     */
    @Override
    public TableDataInfo<XiaoyuanInfoVo> queryPageList(XiaoyuanInfoBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<XiaoyuanInfo> lqw = buildQueryWrapper(bo);
        Page<XiaoyuanInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询校园安全信息列表
     */
    @Override
    public List<XiaoyuanInfoVo> queryList(XiaoyuanInfoBo bo) {
        LambdaQueryWrapper<XiaoyuanInfo> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<XiaoyuanInfo> buildQueryWrapper(XiaoyuanInfoBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<XiaoyuanInfo> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getInfoTitle()), XiaoyuanInfo::getInfoTitle, bo.getInfoTitle());
        lqw.eq(StringUtils.isNotBlank(bo.getInfoPhoto()), XiaoyuanInfo::getInfoPhoto, bo.getInfoPhoto());
        lqw.eq(StringUtils.isNotBlank(bo.getSchoolId()), XiaoyuanInfo::getSchoolId, bo.getSchoolId());
        lqw.like(StringUtils.isNotBlank(bo.getSchoolName()), XiaoyuanInfo::getSchoolName, bo.getSchoolName());
        lqw.eq(StringUtils.isNotBlank(bo.getInfoType()), XiaoyuanInfo::getInfoType, bo.getInfoType());
        lqw.eq(StringUtils.isNotBlank(bo.getInfoTypeZi()), XiaoyuanInfo::getInfoTypeZi, bo.getInfoTypeZi());
        lqw.eq(StringUtils.isNotBlank(bo.getInfoContent()), XiaoyuanInfo::getInfoContent, bo.getInfoContent());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), XiaoyuanInfo::getStatus, bo.getStatus());
        lqw.eq(bo.getFaBuTime() != null, XiaoyuanInfo::getFaBuTime, bo.getFaBuTime());
        lqw.eq(StringUtils.isNotBlank(bo.getInfoYiDu()), XiaoyuanInfo::getInfoYiDu, bo.getInfoYiDu());
        lqw.eq(StringUtils.isNotBlank(bo.getInfoDianZan()), XiaoyuanInfo::getInfoDianZan, bo.getInfoDianZan());
        lqw.eq(bo.getInfoDianZanId() != null, XiaoyuanInfo::getInfoDianZanId, bo.getInfoDianZanId());
        lqw.eq(StringUtils.isNotBlank(bo.getInfoZhuanFa()), XiaoyuanInfo::getInfoZhuanFa, bo.getInfoZhuanFa());
        lqw.eq(bo.getInfoPingLunId() != null, XiaoyuanInfo::getInfoPingLunId, bo.getInfoPingLunId());
        return lqw;
    }

    /**
     * 新增校园安全信息
     */
    @Override
    public Boolean insertByBo(XiaoyuanInfoBo bo) {
        XiaoyuanInfo add = MapstructUtils.convert(bo, XiaoyuanInfo.class);
        bo.setSchoolId(String.valueOf(LoginHelper.getDeptId()));
        bo.setCreateBy(LoginHelper.getUserId());
        bo.setCreateTime(DateUtils.getNowDate());
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setInfoId(add.getInfoId());
        }
        return flag;
    }

    /**
     * 修改校园安全信息
     */
    @Override
    public Boolean updateByBo(XiaoyuanInfoBo bo) {
        XiaoyuanInfo update = MapstructUtils.convert(bo, XiaoyuanInfo.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(XiaoyuanInfo entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除校园安全信息
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 新增校园安全信息评论
     */
    @Override
    public Boolean insertInfoPingLun(InfoPingLunBo bo) {
        List<InfoPingLunBo> infoPingLunList = new ArrayList<>();
        //敏感词过滤
        String infoPingLunContent = bo.getInfoPingLunContent();
        String content = BadWordsUtil.searchBanWords(infoPingLunContent);
        bo.setInfoPingLunContent(content);
        infoPingLunList.add(bo);
        List<InfoPingLun> convert = MapstructUtils.convert(infoPingLunList, InfoPingLun.class);
        return infoPingLunMapper.insertBatch(convert);


    }

    /**
     * 删除评论
     * @param bo
     * @return
     */
    @Override
    public int deletePingLun(InfoPingLunBo bo) {
        return infoPingLunMapper.deletePingLun(bo);
    }

    /**
     * 点赞接口
     * @param bo
     * @return
     */
    @Override
    public int dianZan(XiaoyuanInfoBo bo) {
        Object cacheObject = RedisUtils.getCacheObject(XIAOYUAN_INFO_DIANZAN_USER + bo.getInfoId());
        //获取点赞数量
        Object dianZanNum = RedisUtils.getCacheObject(XIAOYUAN_INFO_DIANZAN + bo.getInfoId());
        if (ObjectUtils.isEmpty(cacheObject)){
            //如果是空,则给这个人点赞
            RedisUtils.setCacheObject(XIAOYUAN_INFO_DIANZAN_USER + bo.getInfoId(), LoginHelper.getUserId());
            if (ObjectUtils.isEmpty(dianZanNum)){
                RedisUtils.setCacheObject(XIAOYUAN_INFO_DIANZAN + bo.getInfoId(),1);
            }else {
                RedisUtils.setCacheObject(XIAOYUAN_INFO_DIANZAN + bo.getInfoId(),(int)dianZanNum + 1);
            }
        }else {
            //删除这个key
            RedisUtils.deleteObject(XIAOYUAN_INFO_DIANZAN_USER + bo.getInfoId());
            int i = (int) dianZanNum - 1;
            if (i < 0){
                i= 0;
            }
            RedisUtils.setCacheObject(XIAOYUAN_INFO_DIANZAN + bo.getInfoId(),i);
        }
        return 1;
    }

    /**
     * 转发接口
     * @param bo
     * @return
     */
    @Override
    public int zhuanFa(XiaoyuanInfoBo bo) {
        //从redis中获取转发数量
        // key =xiaoyuan_info_zhuanfa:xiaoyuan_info表中的info_id
        //value = 转发数量
        Object number = RedisUtils.getCacheObject(XIAOYUAN_INFO_ZHUANFA + bo.getInfoId());
        if (ObjectUtils.isEmpty(number)){
            //如果是空,则给这个信息创建一个转发数量
            RedisUtils.setCacheObject(XIAOYUAN_INFO_ZHUANFA + bo.getInfoId(),1);
        }else {
            //转发数量+1
            RedisUtils.setCacheObject(XIAOYUAN_INFO_ZHUANFA + bo.getInfoId(),(int)number + 1);
        }
        return 1;
    }
}
