package com.jxy.marketall.service.impl;

import com.jxy.common.core.text.Convert;
import com.jxy.common.core.utils.StringUtils;
import com.jxy.common.core.web.Result.AjaxResult;
import com.jxy.common.core.web.Result.PageResult;
import com.jxy.common.redis.service.RedisService;
import com.jxy.common.security.utils.SecurityUtils;
import com.jxy.marketall.dto.*;
import com.jxy.marketall.entity.MarketallPage;
import com.jxy.marketall.entity.Message;
import com.jxy.marketall.mapper.MessageMapper;
import com.jxy.marketall.service.MessageService;
import com.jxy.marketall.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @Description ETF查询业务处理
 * @Date 2022/5/19 17:51
 * @Author 杜懿
 */
@Service
public class MessageServiceImpl implements MessageService {

    @Autowired
    private MessageMapper mapper;

    @Autowired
    private RedisService redisService;

    @Autowired
    private RedisTemplate redisTemplate ;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean submitMsg(SubmitMsgVo vo) throws SQLException {

        //去转义字符和空格
        vo.setMessage(StringUtils.clean(vo.getMessage()));
        vo.setCoinType(StringUtils.clean(vo.getCoinType()));
        vo.setPage(StringUtils.clean(vo.getPage()));

        MarketallPage page = new MarketallPage();
        page.setName(vo.getPage());
        page.setCoinType(vo.getCoinType());

        mapper.insertPage(page);
        long pageId = getPageIdByCleanCond(vo.getPage(), vo.getCoinType());

        if(StringUtils.isNull(pageId)){
            throw new SQLException("对应页面未找到");
        }else if (pageId == 0){
            throw new SQLException("对应页面未找到");
        }

        MsgInsertDto dto = new MsgInsertDto();

        dto.setUserId(SecurityUtils.getUserId());
        dto.setPageId(pageId);
        dto.setMessage(StringUtils.clean(vo.getMessage()));
        System.out.println("留言数据："+dto);
        return mapper.insertMessageByUser(dto);
    }

    @Override
    public AjaxResult getPageMsg(PageMsgVo  vo) {

        if(vo.getPageNum() > 0){
            vo.setPageNum((vo.getPageNum() - 1)*vo.getPageSize());
        }

        long pageId = getPageIdByCleanCond(vo.getPage(),vo.getCoinType());
        if(StringUtils.isNull(pageId)){
            return AjaxResult.error("对应页面未找到");
        }else if (pageId == 0){
            return AjaxResult.error("对应页面未找到");
        }
        //查询当前页面所有留言
        List<Message> pageList = mapper.getMsgByPage(pageId);

        //查询评论（不包括回复） 过滤得到当前用户在页面的根留言
        List<Message> pMsgList = pageList.stream().filter(message -> (message.getUserId() == SecurityUtils.getUserId() && message.getPid() == 0)).collect(Collectors.toList());

        List<PageOriginMsgDto> list = new ArrayList<>();

        //遍历根留言数据 构造返回结构数据 并根据id构造子留言
        pMsgList.stream().forEach(message -> {

            PageOriginMsgDto pDto = new PageOriginMsgDto();
            pDto.setId(message.getId());
            pDto.setUserDate(message.getSendTime());
            pDto.setUserMsg(message.getContent());
            pDto.setUserName(message.getUserName());
            List<PageResponDto> responList = getChildrenList(pageList,message.getId(),message.getUserName());
            pDto.setResponList(responList);

            list.add(pDto);
        });

        PageResult pageResult = new PageResult();
        pageResult.setCount(Convert.toLong(list.size()));
        pageResult.setTotalPage(getTotalPage(list.size(),vo.getPageSize()));
        //根据分页查询条件构造返回数据
        List<PageOriginMsgDto> rList = list.stream().skip(vo.getPageNum()).limit(vo.getPageSize()).collect(Collectors.toList());
        pageResult.setData(rList);

        return AjaxResult.success(pageResult);
    }



    public List<PageResponDto> getChildrenList(List<Message> list ,long pid,String pUserName){

        //从list中过滤出父id为pid的数据
        List<Message> collect = list.stream().filter(message -> message.getPid() == pid).collect(Collectors.toList());

        List<PageResponDto> resultList = new ArrayList<>();

        //递归查询子数据
        collect.stream().forEach(message -> {

            PageResponDto dto = new PageResponDto();
            dto.setResponid(message.getId());
            dto.setRespon(message.getContent());
            dto.setResponDate(message.getSendTime());
            dto.setResponser(message.getUserName());
            dto.setResponList(getChildrenList(list,message.getId(),message.getUserName()));
            dto.setToUser(pUserName);

            resultList.add(dto);
        });

        return resultList;

    }


    @Override
    public AjaxResult getAllMsg(AllMsgVo vo) {

        if (vo.getStatus().intValue() != 0 && vo.getStatus().intValue() != 1){
            vo.setStatus(null);
        }
        if(vo.getPageNum() > 0){
            vo.setPageNum((vo.getPageNum() - 1)*vo.getPageSize());
        }

        List<BackendMsgDto> list = mapper.getAllMsgByStatusAndTime(vo);
        long count = mapper.getAllMsgCountByCondition(vo);

        PageResult result = new PageResult();
        result.setCount(count);
        result.setTotalPage(getTotalPage(Convert.toInt(count),vo.getPageSize()));
        result.setData(list);

        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult getDailyMsgCount(QueryVo vo) {

        List<DailyMsgCountDto> list = new ArrayList<>();

        if(StringUtils.isNull(vo.getStart())&& StringUtils.isNull(vo.getEnd())){
            list =redisService.getCacheList("dailyMsgCount");
        }else {
            //传了时间参数 从数据库拿
            list = mapper.getDailyMsgCount(vo);
        }

        return AjaxResult.success(list);
    }

    @Override
    public AjaxResult responMsg(ResponMsgVo vo) {

        //根据msg_id 查询对应的page_id、
        if(vo.getMsgId() == 0){
            return AjaxResult.error(503,"留言id传参有误");
        }

        Message pMsg = mapper.getMsgByMsgId(vo.getMsgId());

        Message msg = new Message();
        msg.setUserId(SecurityUtils.getUserId());
        msg.setPageId(pMsg.getPageId());
        msg.setPid(vo.getMsgId());
        msg.setIfOrigin(1);

        //判断是否为管理员
        Long roleId = SecurityUtils.getLoginUser().getSysUser().getRoles().get(0).getRoleId();
        if(roleId == 1){
            msg.setMsgFrom(1);
        }
        //数据入库 成功则修改父留言状态

        MsgInsertDto dto = new MsgInsertDto();
        BeanUtils.copyProperties(msg,dto);
        dto.setMessage(StringUtils.clean(vo.getMessage()));
        if(mapper.insertMessageByUser(dto)){
            //留言回复成功 根据msg_id修改父留言status为已处理
            if(mapper.updateMessageStatusByMsgId(dto.getPid())){
                return AjaxResult.success("留言回复成功");
            }else {
                return AjaxResult.error(504,"后台异常，留言回复失败");
            }
        }else{
            return  AjaxResult.error(504,"后台异常，留言回复失败");
        }
    }

    @Override
    public AjaxResult getPrivateMsg(PrivateMsgVo vo) {

        if(StringUtils.isNotNull(vo.getStatus())){
            if (vo.getStatus().intValue() != 1 &&vo.getStatus().intValue() != 0){
                vo.setStatus(null);
            }
        }

        //处理分页请求参数
        if(vo.getPageNum() > 0){
            vo.setPageNum((vo.getPageNum() - 1)*vo.getPageSize());
        }

        //查询留言
        List<PrivateMsgDto> list = mapper.getPrivateMsgByUserIdAndMsgStatus(vo, SecurityUtils.getUserId());
        long count = mapper.getPrivateMsgCountByUserIdAndMsgStatus(vo, SecurityUtils.getUserId());

        PageResult result = new PageResult();
        result.setCount(count);
        result.setTotalPage(getTotalPage(Convert.toInt(count),vo.getPageSize()));
        result.setData(list);

        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult getPageDetail(PageMsgVo vo) {

        long pageId = getPageIdByCleanCond(vo.getPage(),vo.getCoinType());

        PageDetailDto dto = mapper.getPageDetail(pageId);


        Long choose = mapper.getPageChooseByUserId(pageId, SecurityUtils.getUserId());

        if(StringUtils.isNotNull(choose)){
            dto.setChoose(Convert.toInt(choose));
        }

        return AjaxResult.success(dto);
    }

    @Override
    public AjaxResult changePageChooseByUser(PageCommentVo vo) {

        long pageId = getPageIdByCleanCond(vo.getPage(), vo.getCoinType());

        //根据pageId和userId存入数据
        String key = pageId+"::"+SecurityUtils.getUserId();
        if(redisTemplate.opsForHash().hasKey("MAP_USER_LIKED",key)){
            //已有点赞/点踩记录 先保留记录信息 再删除
            int choose = Convert.toInt(redisTemplate.opsForHash().get("MAP_USER_LIKED", key));
            redisTemplate.opsForHash().delete("MAP_USER_LIKED",key);
        }
        redisTemplate.opsForHash().put("MAP_USER_LIKED",key,vo.getChoose());

        //todo 修改操作
        return AjaxResult.success();
    }

    public long getPageIdByCleanCond(String page,String coinType){
        Long id = mapper.getPageIdByPageName(StringUtils.clean(page), StringUtils.clean(coinType));
        if(StringUtils.isNull(id)){
            if(StringUtils.isNull(page) || StringUtils.isNull(coinType)){
                return 0L;
            }
            //未找到 把数据入库
            MarketallPage vo = new MarketallPage();
            vo.setName(StringUtils.clean(page));
            vo.setCoinType(StringUtils.clean(coinType));
            mapper.insertPage(vo);
            id = mapper.getPageIdByPageName(StringUtils.clean(page), StringUtils.clean(coinType));
        }
        return id;
    }

    public long getTotalPage(int count, int size){
        if (size == 0) {
            return 0L;
        }
        long pages = count / size;
        if (count % size != 0) {
            pages++;
        }
        return pages;
    }
}
