package com.rongwei.bscommon.sys.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rongwei.bscommon.sys.dao.SrmIssuesListDao;
import com.rongwei.bscommon.sys.dao.SysNotifyAnnounceDao;
import com.rongwei.bscommon.sys.dao.SysNotifyAnnounceUserDao;
import com.rongwei.bscommon.sys.service.SrmIssuesListService;
import com.rongwei.bsentity.domin.SrmIssuesListDo;
import com.rongwei.bsentity.vo.SrmIssuesListVo;
import com.rongwei.commonservice.service.SysConfigService;
import com.rongwei.rwadmincommon.system.dao.SysUserDao;
import com.rongwei.rwadmincommon.system.domain.SysOrganizationDo;
import com.rongwei.rwadmincommon.system.domain.SysUserDo;
import com.rongwei.rwadmincommon.system.service.SysConfigFeignService;
import com.rongwei.rwadmincommon.system.service.SysOrganizationService;
import com.rongwei.rwadmincommon.system.vo.SysOrganizationVo;
import com.rongwei.rwadmincommon.system.vo.SysUserVo;
import com.rongwei.rwcommon.base.R;
import com.rongwei.rwcommon.utils.SecurityUtil;
import com.rongwei.rwcommon.vo.MailDo;
import com.rongwei.rwcommonentity.commonservers.domain.SysFileItemDo;
import com.rongwei.rwcommonentity.commonservers.domain.SysNotifyAnnounceDo;
import com.rongwei.rwcommonentity.commonservers.domain.SysNotifyAnnounceUserDo;
import com.rongwei.rwcommonentity.commonservers.vo.SysNotifyAnnounceVo;
import com.rongwei.safecommon.utils.CXCommonUtils;
import dto.DeparterAndWorkShoperVo;
import dto.SysNoticeVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Decoder;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

import static com.rongwei.safecommon.utils.CXCommonUtils.DEFAULT_NOTIFY_STATUS;
import static com.rongwei.safecommon.utils.SaveConstans.IssuesListNotice.*;

/**
 * <p>
 * 问题列表 服务实现类
 * </p>
 *
 * @author fpy
 * @since 2023-03-20
 */
@Service
public class SrmIssuesListServiceImpl extends ServiceImpl<SrmIssuesListDao, SrmIssuesListDo> implements SrmIssuesListService {

    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private SrmIssuesListDao srmIssuesListDao;
    @Autowired
    private SysOrganizationService sysOrganizationService;
    @Autowired
    private SysNotifyAnnounceDao sysNotifyAnnounceDao;

    @Autowired
    private SysNotifyAnnounceUserDao sysNotifyAnnounceUserDao;


    @Resource
    private SysConfigFeignService sysConfigFeignService;

    @Autowired
    private SysUserDao sysUserDao;

    private final Logger log = LoggerFactory.getLogger(this.getClass().getName());




    @Override
    public void saveFishBoneImg(SrmIssuesListDo srmIssuesListDo) throws IOException {
        if (srmIssuesListDo.getCauseanalysisimg() != null) {
            String imgUrl = this.base64ImgSave(srmIssuesListDo.getCauseanalysisimg());
            srmIssuesListDo.setCauseanalysisimg(imgUrl.split("@_@")[0]);
            srmIssuesListDo.setCauseanalysisimgurl(imgUrl.split("@_@")[1]);
        }
        if (srmIssuesListDo.getUndetectedanalysisimg() != null) {
            String imgUrl = this.base64ImgSave(srmIssuesListDo.getUndetectedanalysisimg());
            srmIssuesListDo.setUndetectedanalysisimg(imgUrl.split("@_@")[0]);
            srmIssuesListDo.setUndetectedanalysisimgurl(imgUrl.split("@_@")[1]);
        }
        this.updateById(srmIssuesListDo);
    }

    private String base64ImgSave(String imgContent) throws IOException {
        // 替换到头部标识信息
        imgContent = imgContent.replace("data:image/png;base64,", "");
        // 获取存储文件路径
        String fileRootPath = sysConfigService.getContentByConfigCode("fileRootPath");
        String fileName = SecurityUtil.getUUID() + ".png";
        String imgPath = fileRootPath + File.separator + "mindImg" + File.separator + fileName;
        // 写入文件内容
        File file = new File(imgPath);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        byte[] buffer = new BASE64Decoder().decodeBuffer(imgContent);
        FileOutputStream out = new FileOutputStream(imgPath);
        out.write(buffer);
        out.close();

        //成功存储图片后，将文件存入系统文件中（sys_file_item），组装返回图片字段
        SysUserVo currentUser = CXCommonUtils.getCurrentUser();
        SysFileItemDo sysFileItemDo = new SysFileItemDo();
        sysFileItemDo.setId(SecurityUtil.getUUID());
        sysFileItemDo.setFilename(fileName);
        //文件大小
        sysFileItemDo.setFilesize(file.length());
        sysFileItemDo.setFiletype("png");
        sysFileItemDo.setStoragetype("1");
        sysFileItemDo.setFilefolderid("83968772af5042f4b09168e1ee74eac8");
        sysFileItemDo.setRelationid("83968772af5042f4b09168e1ee74eac8");
        sysFileItemDo.setFullpath(imgPath);
        sysFileItemDo.setUrlpath("/files/mindImg/" + fileName);
        sysFileItemDo.setExtends1("files");
        sysFileItemDo.setDeleted("0");
        sysFileItemDo.setCreatedate(DateUtil.date());
        sysFileItemDo.setCreateuserid(currentUser.getId());
        sysFileItemDo.setModifydate(DateUtil.date());
        sysFileItemDo.setModifyuserid(currentUser.getId());
        sysFileItemDo.setCreateusername(currentUser.getName());
        sysFileItemDo.setModifyusername(currentUser.getName());
        this.baseMapper.insertFile(sysFileItemDo);
        //打包文件名称和ID
        String imgUrl = fileName + "-;-" + sysFileItemDo.getId();
        imgPath = imgPath + "@_@" + imgUrl;

        return imgPath;
    }

    /**
     * 获取问题列表
     *
     * @param mesIds
     * @return
     */
    public List<SrmIssuesListDo> getListByMesId(List<String> mesIds) {
        return srmIssuesListDao.getListByMesId(mesIds);
    }

    @Override
    public void productionOverdue() {
        //查询需要推送和修改的消息
        List<SysNoticeVo> list = this.baseMapper.selectNoticeByProduct();
        //没有消息，直接结束
        if (list.size() <= 0) {
            return;
        }
        //有消息将消息的NOTIFYTYPE改为production_overdue
        List<String> idList = list.stream().map(SysNotifyAnnounceVo::getId).collect(Collectors.toList());
        this.baseMapper.updateNoticeByProduct(idList);
        //将消息发送给app
        for (SysNoticeVo sysNoticeVo : list) {
            String title = sysNoticeVo.getNotifytitle();
            String content = sysNoticeVo.getNotifycontent();
            List<String> userIdList = Arrays.asList(sysNoticeVo.getRecipientIds().split(","));
            CXCommonUtils.pushApp(title, content, userIdList);
        }

    }

    @Override
    public R getUsersDepartBmzAndCjzr() {
        SysUserVo currentUser = CXCommonUtils.getCurrentUser();
        //获取当前用户的部门信息
        SysOrganizationVo sysOrganizationVo = currentUser.getOrganizationDoList().get(0);
        //==========开始溯源=============
        //最终的车间ID
        String endOrgId = "";
        //如果当前用户的部门本身为 chejian 等级，溯源结果为当前车间
        if (ObjectUtil.isNotEmpty(sysOrganizationVo.getOrgtype()) && sysOrganizationVo.getOrgtype().equals("chejian")) {
            endOrgId = sysOrganizationVo.getId();
        } else if (sysOrganizationVo.getPid().equals("-1")) {
            endOrgId = "";
        } else {
            //迭代 溯源 chejian 部门
            endOrgId = selectChejian(sysOrganizationVo.getPid());
        }
        List<DeparterAndWorkShoperVo> res = new LinkedList<>();
        //查询对应部门 以及子部门 的 部门长和车间主任
        if (ObjectUtil.isNotEmpty(endOrgId)) {
            res = this.baseMapper.selectDeparterAndWorkShoper(endOrgId);
        }

        return R.ok(res);
    }



    String selectChejian(String startDepartId) {
        if (ObjectUtil.isEmpty(startDepartId)) {
            return "";
        }
        SysOrganizationDo sysOrganizationDo = sysOrganizationService.getById(startDepartId);
        if (ObjectUtil.isNotEmpty(sysOrganizationDo.getOrgtype()) && sysOrganizationDo.getOrgtype().equals("chejian")) {
            return sysOrganizationDo.getId();
        } else if (sysOrganizationDo.getPid().equals("-1")) {
            return "";
        } else {
            return selectChejian(sysOrganizationDo.getPid());
        }
    }


    /**
     * 生产问题审批超时提醒
     * @return
     */
    @Override
    public R approvalTimeoutReminder() {
        log.info("生产问题审批超时提醒开始：");
        String taskname=null;
        long fourHoursInMillis = 4 * 60 * 60 * 1000; // 4小时转换为毫秒
        long twentyFourHoursInMillis = 24 * 60 * 60 * 1000; // 24小时转换为毫秒
        long fortyEightHoursInMillis = 48 * 60 * 60 * 1000; // 48小时转换为毫秒
        Map<String, List<SysNotifyAnnounceDo>> keyMap =new HashMap<String,  List<SysNotifyAnnounceDo>>();   //主表 id ,remark
        Map<String, String> issTaskkey =new HashMap<String, String>(); // 主表id , 消息提醒表 id
        List<SrmIssuesListVo> userEmailList =  new ArrayList<>();

        //1.查询所有未审批，审批中的数据
        List<SrmIssuesListVo> list =  srmIssuesListDao.selectTimeOutData();
        //2.查询跟踪类型的所有提醒
        LambdaQueryWrapper<SysNotifyAnnounceDo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysNotifyAnnounceDo::getDeleted,0)
                .eq(SysNotifyAnnounceDo::getNotifytype,ISSUES_NOTICE_NOTIFYTYPE)
                .likeRight(SysNotifyAnnounceDo::getRemark,ISSUES_REMARK_NEW);
        List<SysNotifyAnnounceDo> sysNotifyAnnounceDoList =
                sysNotifyAnnounceDao.selectList(queryWrapper);
        if (!sysNotifyAnnounceDoList.isEmpty()){
           keyMap = sysNotifyAnnounceDoList.stream().collect(Collectors.groupingBy(SysNotifyAnnounceDo::getRoption));
        }

        Boolean f=false;
        //2 查询消息提醒中
        for(SrmIssuesListVo vo:list){
            taskname = vo.getTaskname();
            try {

                    //2.条件判断节点跟超时时间截取数据
                    if (taskname.equals("问题登记人") && System.currentTimeMillis()- vo.getCreatedate().getTime() > twentyFourHoursInMillis){
                        vo.setNodetime(vo.getCreatedate());
                        vo.setOperationid(vo.getCreateuserid());
                        vo.setHour(24);
                        f= true;
                    } else if ((taskname.equals("部门长") || taskname.equals("生产副总") || taskname.equals("责任部门长") || taskname.equals("责任部长审核") || taskname.equals("车间主任/部门经理审核")
                            || taskname.equals("车间主任/经理审核")  || taskname.equals("发起人确认")  || taskname.equals("领导审核") || taskname.equals("SPA跟踪"))
                            && System.currentTimeMillis()- vo.getNodetime().getTime() > fourHoursInMillis) {
                        f= true;vo.setHour(4);
                    }else if ( (taskname.equals("SPA") || taskname.equals("任务SPA")   || taskname.equals("SPA维护标准化文件"))
                            && System.currentTimeMillis()- vo.getNodetime().getTime() > fortyEightHoursInMillis) {
                        f= true;vo.setHour(48);
                    }
                    if (f){
                        // 生成个人工作台提醒
                        addNotifyAnnounce(vo,userEmailList,keyMap, issTaskkey);
                    }
                    f=false;

            }catch (Exception e){
                log.error(" 节点 {} 问题编号 {} 出现问题 {} ",taskname,vo.getQuestionno(),e.getMessage());
            }
        }

        //3.发送邮件
        log.info("开始发送邮件，人员数量{}",userEmailList.size());
        sendIssuesListEmail(userEmailList);
        log.info("生产问题审批超时提醒结束：");
        return R.ok();
    }

    /**
     * 整理发送邮件
     * @param userEmailList
     */
    private void sendIssuesListEmail(List<SrmIssuesListVo> userEmailList) {
        //获取人员邮件
        List<SysUserDo> sysUserDos = sysUserDao.selectList(new LambdaQueryWrapper<SysUserDo>().eq(SysUserDo::getDeleted, "0").isNotNull(SysUserDo::getEmail));
        Map<String, String> userEmailKey = sysUserDos.stream().collect(Collectors.toMap(SysUserDo::getId, SysUserDo::getEmail));
        StringBuilder content = new StringBuilder();
        if (!userEmailList.isEmpty()) {
            Map<String, Map<String, List<SrmIssuesListVo>>> result = userEmailList.stream()
                    .collect(Collectors.groupingBy(
                            SrmIssuesListVo::getEmailUserid, // 外部分组键
                            Collectors.groupingBy(SrmIssuesListVo::getTaskname) // 内部分组键，使用内部groupingBy收集器
                    ));
            for (String userid:result.keySet()) {
                if (userEmailKey.get(userid) != null) {
                    MailDo mailDo = new MailDo();
                    mailDo.setSubject(ISSUES_EMAIL_TITLE);
                    mailDo.setReceiveEmail(new String[]{userEmailKey.get(userid)});
                 //   mailDo.setReceiveEmail(new String[]{"1311562099@qq.com"});
                    mailDo.setNeedTransReceive(false);
                    content = new StringBuilder();
                    for (String name: result.get(userid).keySet()) {
                        List<SrmIssuesListVo> srmIssuesListVos = result.get(userid).get(name);
                        for (int i = 1; i <= srmIssuesListVos.size(); i++) {
                            if (i==1){
                                content.append("您好！ 有【"+srmIssuesListVos.size()+"】条生产问题在【"+name+"】已经超过【"+srmIssuesListVos.get(i-1).getHour()+"】小时没有处理，请尽快处理！\n");
                            }
                            content.append(i+srmIssuesListVos.get(i-1).getReminder()+"\n");
                        }
                    }
                    content.append("详见问题跟踪与解决系统，如果无法点击请复制链接到浏览器中：http://192.168.100.77/#/dashboarditem/8c1b2d26e77947c98c4a4668d687aba2");
                    mailDo.setContent(content.toString());
                    try {
                        sysConfigFeignService.sendTextMail(mailDo);

                    } catch (Exception ignored) {
                    }
                }
            }
        }
    }

    /**
     * 添加工作台提醒消息
     *
     * @param
     * @param
     * @param vo

     * @param keyMap

     * @return
     */
    private void addNotifyAnnounce(SrmIssuesListVo vo, List<SrmIssuesListVo> userEmailList, Map<String, List<SysNotifyAnnounceDo>> keyMap, Map<String, String> issTaskkey) {

      String    title ="【生产问题审批超时提醒】--生产问题【"+vo.getQuestionno()+"】【"+vo.getQuestiontitle()+"】已经超过"+vo.getHour()+"小时没有处理，请尽快处理！";

        if (!keyMap.isEmpty() && keyMap.containsKey(vo.getId()) && keyMap.get(vo.getId()).get(0).getRemark().equals(ISSUES_REMARK_NEW+"-"+vo.getId()+"-"+vo.getNodetime().getTime())){
            //超时限制内的数据，不做处理
            return;
        }

        if  (!keyMap.isEmpty() && keyMap.containsKey(vo.getId()) && !keyMap.get(vo.getId()).get(0).getRemark().equals(ISSUES_REMARK_NEW+"-"+vo.getId()+"-"+vo.getNodetime().getTime())){
            //并且处理老数据,更换主表 remark 标识
            String remark = keyMap.get(vo.getId()).get(0).getRemark().replace(ISSUES_REMARK_NEW, ISSUES_REMARK_OLD);
            LambdaUpdateWrapper<SysNotifyAnnounceDo> announceUpdateWrapper = new LambdaUpdateWrapper<>();
            announceUpdateWrapper.eq(SysNotifyAnnounceDo::getId,keyMap.get(vo.getId()).get(0).getId()).eq(SysNotifyAnnounceDo::getDeleted,0)
                    .set(SysNotifyAnnounceDo::getRemark,remark); //已读
            sysNotifyAnnounceDao.update(null,announceUpdateWrapper);
            //并且处理老数据,子表更换已读
            LambdaUpdateWrapper<SysNotifyAnnounceUserDo> userUpdateWrapper = new LambdaUpdateWrapper<>();
            userUpdateWrapper.eq(SysNotifyAnnounceUserDo::getAnnounceid,keyMap.get(vo.getId()).get(0).getId()).eq(SysNotifyAnnounceUserDo::getDeleted,0)
                    .set(SysNotifyAnnounceUserDo::getReadstate,ISSUES_READ_STATUS); //已读
            sysNotifyAnnounceUserDao.update(null,userUpdateWrapper);

        };

        SysNotifyAnnounceDo sysNotifyAnnounceDo=new SysNotifyAnnounceDo();
        //流程部门是有并签处理，过滤下数据
        if (issTaskkey.containsKey(vo.getId())){
            sysNotifyAnnounceDo.setId(issTaskkey.get(vo.getId()));
        }else {
            sysNotifyAnnounceDo.setId(SecurityUtil.getUUID());
            sysNotifyAnnounceDo.setSenderid(ISSUES_NOTICE_SENDERID);
            sysNotifyAnnounceDo.setNotifytitle(ISSUES_NOTICE_NOTIFYTITLE);
            sysNotifyAnnounceDo.setNotifytype(ISSUES_NOTICE_NOTIFYTYPE);
            sysNotifyAnnounceDo.setNotifystatus(DEFAULT_NOTIFY_STATUS);
            sysNotifyAnnounceDo.setNotifycontent(title);
            sysNotifyAnnounceDo.setRoption(vo.getId());
            sysNotifyAnnounceDo.setRemark(ISSUES_REMARK_NEW+"-"+vo.getId()+"-"+vo.getNodetime().getTime());
            sysNotifyAnnounceDo.setCreatedate(new Date());
            sysNotifyAnnounceDo.setModifydate(new Date());
            sysNotifyAnnounceDo.setModifyusername("定时任务");
            sysNotifyAnnounceDao.insert(sysNotifyAnnounceDo);
            issTaskkey.put(vo.getId(),sysNotifyAnnounceDo.getId());
        }

        String userArr[] = null;
        SysNotifyAnnounceUserDo sysNotifyAnnounceUserDo = new SysNotifyAnnounceUserDo();
        userArr = vo.getOperationid().split(",");
        SrmIssuesListVo srmIssuesListVo =null;
        for (String userId : userArr){
            sysNotifyAnnounceUserDo.setId(SecurityUtil.getUUID());
            sysNotifyAnnounceUserDo.setAnnounceid(sysNotifyAnnounceDo.getId());
            sysNotifyAnnounceUserDo.setRecipientid(userId);
            sysNotifyAnnounceUserDo.setReadstate(ISSUES_UNREAD_STATUS);//未读
            sysNotifyAnnounceUserDo.setCreatedate(new Date());
            sysNotifyAnnounceUserDo.setModifydate(new Date());
            sysNotifyAnnounceUserDo.setModifyusername("定时任务");
            sysNotifyAnnounceUserDao.insert(sysNotifyAnnounceUserDo);
            srmIssuesListVo =new SrmIssuesListVo();
            srmIssuesListVo.setEmailUserid(userId);
            srmIssuesListVo.setTaskname(vo.getTaskname());
            if (vo.getTaskname().equals("问题登记人")){
                srmIssuesListVo.setReminder("、【"+vo.getQuestionno()+"】【"+vo.getQuestiontitle()+"】已创建，请及时提交流程！");
            }else {
                srmIssuesListVo.setReminder("、【"+vo.getQuestionno()+"】【"+vo.getQuestiontitle()+"】已提交审批，请尽快完成审批！");
            }
            srmIssuesListVo.setHour(vo.getHour());
            userEmailList.add(srmIssuesListVo);
        }
    }
}
