package cn.iocoder.yudao.module.workReport.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.common.SystemEnum;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.system.api.user.dto.UserDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.service.permission.RoleService;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import cn.iocoder.yudao.module.workReport.entity.WorkReport;
import cn.iocoder.yudao.module.workReport.mapper.WorkReportMapper;
import cn.iocoder.yudao.module.workReport.service.WorkReportService;
import cn.iocoder.yudao.module.workReport.vo.WorkReportPageReqVO;
import cn.iocoder.yudao.module.workReport.vo.WorkReportRespVO;
import cn.iocoder.yudao.module.workReport.vo.WorkReportSaveReqVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.common.BaseConstants.TICKET_EMPLOY;


/**
 * 工作汇报 Service 实现类
 *
 * @author lighting
 */
@Service
@Validated
public class WorkReportServiceImpl extends ServiceImpl<WorkReportMapper, WorkReport> implements WorkReportService {

    @Resource
    private WorkReportMapper reportMapper;

    @Resource
    private DictDataApi dictDataApi;

    @Resource
    private RoleService roleService;

    @Resource
    private PermissionApi permissionApi;

    @Resource
    private AdminUserService adminUserService;


    @Resource
    private NotifyMessageSendApi sendApi;

    @Resource
    private AdminUserApi userApi;

    @Override
    public Integer createReport(WorkReportSaveReqVO createReqVO) {
        // 插入
        WorkReport report = BeanUtils.toBean(createReqVO, WorkReport.class);
        // 设置汇报时间为当前时间
        report.setReportTime(LocalDateTime.now());

        // 将汇报对象集合转换为字符串
        report.setReportTo(createReqVO.getReportTos().stream().map(String::valueOf).collect(Collectors.joining(",")));

        reportMapper.insert(report);

        // 获取汇报人姓名
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        AdminUserRespDTO user = userApi.getUser(userId);
        String userName = user.getNickname();

        // 消息内容
        String message = "向您进行了工作汇报，请在内部管理中查阅！";
        String text = userName + message;

        // 发送消息给汇报对象
        this.sendMessage(createReqVO.getReportTos(), text, createReqVO.getServicePackageId());
        // 根据服务套餐id进行发送
        /*if("jiaxiao".equals(createReqVO.getServicePackageId())){
            this.sendMessage(createReqVO.getReportTos(), text, createReqVO.getServicePackageId());
        }else if("jiance".equals(createReqVO.getServicePackageId())){
            this.sendMessage(createReqVO.getReportTos(), text, createReqVO.getServicePackageId());
        }*/
        // 返回
        return report.getId();
    }

    @Override
    public void updateReport(WorkReportSaveReqVO updateReqVO) {
        // 校验存在
        validateReportExists(updateReqVO.getId());
        // 将汇报对象集合转换为字符串
        updateReqVO.setReportTo(updateReqVO.getReportTos().stream().map(String::valueOf).collect(Collectors.joining(",")));
        // 更新
        WorkReport updateObj = BeanUtils.toBean(updateReqVO, WorkReport.class);
        reportMapper.updateById(updateObj);
    }

    @Override
    public void deleteReport(Integer id) {
        // 校验存在
        validateReportExists(id);
        // 删除
        reportMapper.deleteById(id);
    }

    private void validateReportExists(Integer id) {
        if (reportMapper.selectById(id) == null) {
            throw new RuntimeException("工作汇报不存在");
        }
    }

    @Override
    public WorkReport getReport(Integer id) {
        return reportMapper.selectById(id);
    }

    @Override
    public IPage<WorkReportRespVO> getReportPage(Page<WorkReport> page, WorkReportPageReqVO pageReqVO) {
        //判断当前登陆人的角色是否是公司高层
        boolean isCompanyLeader = permissionApi.hasDictTypeRole(pageReqVO.getDictType());
        if (isCompanyLeader) {
            pageReqVO.setUserId(null);
        }
        return reportMapper.selectPage(page, pageReqVO);
    }

    /**
     * 发送消息
     * @param userIdS  接收人id集合
     * @param text     消息内容
     * @param code     服务套餐id
     */
    public void sendMessage(List<Long> userIdS, String text, String code) {
        // 准备发送参数
        Map<String, Object> templateParams = new HashMap<>();
        // 发送模版内容
        templateParams.put("text", text);
        // 发送站内信
        userIdS.forEach(userId -> {
            sendApi.sendSingleMessageToAdmin(new NotifySendSingleToUserReqDTO()
                    .setUserId(userId)
                    .setTemplateCode(TICKET_EMPLOY)
                    .setSystemCode(code)
                    .setTemplateParams(templateParams));
        });

    }

    /**
     * 查询汇报对象
     *
     * @param dictType 字典类型
     * @return
     */
    @Override
    public List<UserDTO> queryReportTo(String dictType) {
        //根据dictType查询角色
        List<DictDataRespDTO> roleList = dictDataApi.getDictDataList(dictType);
        if (CollUtil.isEmpty(roleList)) {
            throw new RuntimeException("暂未分配汇报对象");
        }
        List<String> codes = roleList.stream().map(DictDataRespDTO::getValue).collect(Collectors.toList());

        //根据角色查询用户
        return roleService.getUserListByCodes(codes);
    }

    /**
     * 查询汇报对象数量
     *
     * @return
     */
    @Override
    public Long queryReportCount(WorkReportPageReqVO pageReqVO) {
        return reportMapper.queryReportCount(pageReqVO);
    }

    /**
     * 工作汇报预览
     *
     * @param id 工作汇报id
     * @return 工作汇报详情
     */
    @Override
    public String workReportView(Integer id) {

        String html = "<div style=\"display: flex; justify-content: center; align-items: center; width: 100%;\">\n" +
                "  <table style=\"width: 99.0769%; height: 240.594px; border-collapse: collapse; border: 1px solid black;\" data-sort=\"sortDisabled\">\n" +
                "    <tbody>\n" +
                "      <tr class=\"firstRow\" style=\"height: 19.5938px;\">\n" +
                "        <td style=\"word-break: break-all; width: 99.9716%; text-align: center; height: 19.5938px; border: 1px solid black;\" colspan=\"2\" valign=\"top\" width=\"756.3333333333334\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 工作汇报</td>\n" +
                "      </tr>\n" +
                "      <tr style=\"height: 45px;\">\n" +
                "        <td style=\"word-break: break-all; width: 14.5491%; height: 45px; border: 1px solid black;\" valign=\"top\" width=\"105.33333333333333\" height=\"45\">汇报主题</td>\n" +
                "        <td style=\"word-break: break-all; width: 85.4226%; height: 45px; border: 1px solid black;\" colspan=\"1\" valign=\"top\" width=\"630.3333333333334\" height=\"45\">reportTopic</td>\n" +
                "      </tr>\n" +
                "      <tr style=\"height: 47px;\">\n" +
                "        <td style=\"word-break: break-all; width: 14.5491%; height: 47px; border: 1px solid black;\" valign=\"top\" width=\"105.33333333333333\" height=\"47\">汇报对象</td>\n" +
                "        <td style=\"word-break: break-all; width: 85.4226%; height: 47px; border: 1px solid black;\" valign=\"top\" width=\"630.3333333333334\" height=\"47\">reportToStr</td>\n" +
                "      </tr>\n" +
                "      <tr style=\"height: 43px;\">\n" +
                "        <td style=\"word-break: break-all; width: 14.5491%; height: 43px; border: 1px solid black;\" valign=\"top\" width=\"105.33333333333333\" height=\"43\">汇报内容</td>\n" +
                "        <td style=\"word-break: break-all; width: 85.4226%; height: 43px; border: 1px solid black;\" valign=\"top\" width=\"630.3333333333334\" height=\"43\">reportContent</td>\n" +
                "      </tr>\n" +
                "      <tr style=\"height: 41px;\">\n" +
                "        <td style=\"word-break: break-all; width: 14.5491%; height: 41px; border: 1px solid black;\" valign=\"top\" width=\"105.33333333333333\" height=\"41\">汇报人</td>\n" +
                "        <td style=\"word-break: break-all; width: 85.4226%; height: 41px; border: 1px solid black;\" valign=\"top\" width=\"630.3333333333334\" height=\"41\">userName</td>\n" +
                "      </tr>\n" +
                "      <tr style=\"height: 45px;\">\n" +
                "        <td style=\"word-break: break-all; width: 14.5491%; height: 45px; border: 1px solid black;\" colspan=\"1\" rowspan=\"1\" valign=\"top\" height=\"45\">汇报时间</td>\n" +
                "        <td style=\"word-break: break-all; width: 85.4226%; height: 45px; border: 1px solid black;\" colspan=\"1\" rowspan=\"1\" valign=\"top\" width=\"630.3333333333334\" height=\"45\">reportTime</td>\n" +
                "      </tr>\n" +
                "    </tbody>\n" +
                "  </table>\n" +
                "</div>\n" +
                "<p>&nbsp;</p>\n";

        WorkReportPageReqVO pageReqVO = new WorkReportPageReqVO();
        pageReqVO.setId(id);
        WorkReportRespVO workReport = reportMapper.selectByIdOne(pageReqVO);
        List<Long> userIds = Arrays.stream(workReport.getReportTo().split(",")).map(Long::parseLong)
                .collect(Collectors.toList());

        List<AdminUserDO> userList = adminUserService.getUserList(userIds);
        List<String> userNames = userList.stream().map(item -> item.getNickname()).collect(Collectors.toList());
        String reportToStr = String.join(",", userNames);
        //替换字符串
        html = html.replace("reportTopic", workReport.getReportTopic());
        html = html.replace("reportToStr", reportToStr);
        html = html.replace("reportContent", workReport.getReportContent());
        html = html.replace("userName", workReport.getUserName());
        html = html.replace("reportTime", DateUtil.format(workReport.getReportTime(), "yyyy-MM-dd HH:mm"));
        return html;
    }

}
