package cn.iocoder.yudao.module.system.service.comment;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import cn.iocoder.yudao.module.system.api.subscribe.SubscribeMessageSendApi;
import cn.iocoder.yudao.module.system.controller.admin.worklog.vo.loginstance.LogInstanceRespVO;
import cn.iocoder.yudao.module.system.controller.app.comment.dto.CommentDTO;
import cn.iocoder.yudao.module.system.controller.app.comment.vo.CommentPageListVO;
import cn.iocoder.yudao.module.system.controller.app.comment.vo.CommentTypeCountVO;
import cn.iocoder.yudao.module.system.controller.app.comment.vo.WorkLogCommentPageReqVO;
import cn.iocoder.yudao.module.system.controller.app.comment.vo.WorkLogCommentSaveReqVO;
import cn.iocoder.yudao.module.system.convert.worklog.LogCommentConvert;
import cn.iocoder.yudao.module.system.dal.dataobject.comment.WorkLogCommentDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.dal.dataobject.worklog.LogFormDO;
import cn.iocoder.yudao.module.system.dal.mysql.comment.WorkLogCommentMapper;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import cn.iocoder.yudao.module.system.service.worklog.LogFormService;
import cn.iocoder.yudao.module.system.service.worklog.LogInstanceService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 工作日志评论 Service 实现类
 *
 * @author 艾楷
 */
@Service
@Validated
public class WorkLogCommentServiceImpl implements WorkLogCommentService {

    @Resource
    private WorkLogCommentMapper workLogCommentMapper;
    @Resource
    private LogFormService logFormService;

    @Resource
    private AdminUserService userService;

    @Resource
    private LogInstanceService logInstanceService;

    @Resource
    private SubscribeMessageSendApi subscribeMessageSendApi;

    @Override
    public Long createWorkLogComment(WorkLogCommentSaveReqVO createReqVO) {
        // 插入
        WorkLogCommentDO workLogComment = BeanUtils.toBean(createReqVO, WorkLogCommentDO.class);
        Long userId = WebFrameworkUtils.getLoginUserId();
        workLogComment.setUserId(userId);
        workLogCommentMapper.insert(workLogComment);

        //创建评论、回复后， 发送消息通知
        sendMessage(workLogComment);

        // 返回
        return workLogComment.getId();
    }

    @Override
    public void updateWorkLogComment(WorkLogCommentSaveReqVO updateReqVO) {
        // 校验存在
//        validateWorkLogCommentExists(updateReqVO.getId());
        // 更新
        WorkLogCommentDO updateObj = BeanUtils.toBean(updateReqVO, WorkLogCommentDO.class);
        workLogCommentMapper.updateById(updateObj);
    }

    @Override
    public void deleteWorkLogComment(Long id) {
        // 校验存在
//        validateWorkLogCommentExists(id);
        // 删除
        workLogCommentMapper.deleteById(id);
    }

//    private void validateWorkLogCommentExists(Long id) {
//        if (workLogCommentMapper.selectById(id) == null) {
//            throw exception(WORK_LOG_COMMENT_NOT_EXISTS);
//        }
//    }

    @Override
    public WorkLogCommentDO getWorkLogComment(Long id) {
        return workLogCommentMapper.selectById(id);
    }

    @Override
    public PageResult<WorkLogCommentDO> getWorkLogCommentPage(WorkLogCommentPageReqVO pageReqVO) {
        return workLogCommentMapper.selectPage(pageReqVO);
    }

    @Override
    public IPage<CommentPageListVO> queryCommentPageList(Page<CommentPageListVO> page, CommentDTO dto) {
        if (dto.getCheckMyselfFlag() == 1) {
            Long userId = WebFrameworkUtils.getLoginUserId();
            dto.setUserId(userId);
        }
        IPage<CommentPageListVO> pageList = workLogCommentMapper.queryCommentPageList(page, dto);
        List<CommentPageListVO> records = pageList.getRecords();
        if (dto.getIsShowWorkLogContent() != null && dto.getIsShowWorkLogContent() == 1 && !records.isEmpty()) {
            //模版ids过滤
            List<Long> workFormIds = records.stream().map(CommentPageListVO::getWorkFormId).collect(Collectors.toList());
            //  查询模版列表
            List<LogFormDO> formList = logFormService.getFormList(workFormIds);
            Map<Long, LogFormDO> formMap = formList.stream().collect(Collectors.toMap(LogFormDO::getId, item -> item));
            pageList.getRecords().forEach(item -> {
                LogFormDO logFormDO = formMap.get(item.getWorkFormId());
                List<String> fields = logFormDO.getFields();
                StringBuilder workLogContent = new StringBuilder();
                if (StrUtil.isNotEmpty(item.getWorkLogContent())) {
                    JSONObject workLogContentJson = new JSONObject(item.getWorkLogContent());
                    for (String fieldItem : fields) {
                        JSONObject fieldJson = new JSONObject(fieldItem);
                        String fieldStr = fieldJson.getStr("field");
                        String title = fieldJson.getStr("title");
                        String field = workLogContentJson.getStr(fieldStr);
                        workLogContent.append(title).append(":").append(field);
                    }
                }
                item.setWorkLogContent(workLogContent.toString());
            });
        }
        return pageList;
    }

    @Override
    public CommentTypeCountVO queryCommentTypeCount() {
        Long userId = WebFrameworkUtils.getLoginUserId();
        CommentTypeCountVO vo = new CommentTypeCountVO();
        Integer commentNum = Math.toIntExact(workLogCommentMapper.selectCount(new LambdaQueryWrapper<WorkLogCommentDO>()
                .eq(WorkLogCommentDO::getUserId, userId)
                .eq(WorkLogCommentDO::getType, 0)));
        Integer replyNum = Math.toIntExact(workLogCommentMapper.selectCount(new LambdaQueryWrapper<WorkLogCommentDO>()
                .and(a -> a.eq(WorkLogCommentDO::getUserId, userId)
                        .or().eq(WorkLogCommentDO::getCommentUserId, userId))
                .eq(WorkLogCommentDO::getType, 1)));
        vo.setCommentNum(commentNum);
        vo.setReplyNum(replyNum);
        vo.setAllNum(commentNum + replyNum);
        return vo;
    }

    /**
     * 评论或回复 发送消息通知
     */
    private void sendMessage(WorkLogCommentDO workLogComment) {

        //获得日志详情
        LogInstanceRespVO instanceDO = logInstanceService.getLogInstance(workLogComment.getWorkLogId());

        //获得 用户信息Map
        Map<Long, AdminUserDO> userMap = userService.getUserMap(Arrays.asList(instanceDO.getStartUserId(), workLogComment.getUserId()));

        String openId = userMap.get(instanceDO.getStartUserId()).getOpenId();

        if (openId != null) {

            //发送消息通知
            subscribeMessageSendApi.sendWorkLogComment(LogCommentConvert.INSTANCE.convertLogComment(
                    openId, workLogComment, userMap.get(workLogComment.getUserId()).getNickname(),
                    "formal"));
        }

    }
}