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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.system.SystemUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rongwe.scentity.domian.*;
import com.rongwe.scentity.vo.PointCheckItemVo;
import com.rongwe.scentity.vo.PointCheckVo;
import com.rongwei.commonservice.serial.service.CommonDictService;
import com.rongwei.commonservice.serial.service.SysSerialNumberService;
import com.rongwei.rwadmincommon.system.domain.SysUserDo;
import com.rongwei.rwadmincommon.system.domain.SysUserOrgDo;
import com.rongwei.rwadmincommon.system.service.SysConfigFeignService;
import com.rongwei.rwadmincommon.system.service.SysUserOrgService;
import com.rongwei.rwadmincommon.system.service.SysUserService;
import com.rongwei.rwcommon.base.QueryPar;
import com.rongwei.rwcommon.utils.SecurityUtil;
import com.rongwei.rwcommon.utils.StringUtils;
import com.rongwei.rwcommon.vo.MailDo;
import com.rongwei.rwcommonentity.commonservers.vo.SysSerialVo;
import com.rongwei.sfcommon.sys.dao.PointCheckDao;
import com.rongwei.sfcommon.sys.service.*;
import com.rongwei.sfcommon.utils.MlConstants;
import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationTargetException;
import java.util.*;

import static com.rongwei.sfcommon.utils.CommonUtil.streamCodeGeneration;

@Service("pointCheckService")
public class PointCheckServiceImpl extends ServiceImpl<PointCheckDao, PointCheckDo> implements PointCheckService {

    private static final Logger logger = LoggerFactory.getLogger(PointCheckServiceImpl.class);

    @Autowired
    private PointCheckItemService pointCheckItemService;
    @Autowired
    private HiddenDangerTrackService hiddenDangerTrackService;
    @Autowired
    private CheckItemsService checkItemsService;
    @Autowired
    private CommonDictService commonDictService;
    @Autowired
    private PointCheckDao pointCheckDao;
    @Autowired
    private SysConfigFeignService sysConfigFeignService;
    @Autowired
    private SysSerialNumberService sysSerialNumberService;
    @Autowired
    private CheckItemContentService checkItemContentService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysUserOrgService sysUserOrgService;

    /**
     * 查询点检列表
     *
     * @param pointCheckVo
     * @return
     */
    @Override
    public IPage<PointCheckVo> pointCheckList(QueryPar<PointCheckVo> pointCheckVo) {
        if (MlConstants.POINT_CHECK_STATUS_HAS.equals(pointCheckVo.getParameter().getCheckstatus())) {
            // 已点检
            String userid = pointCheckVo.getParameter().getUserid();
            if (StringUtils.isNotEmpty(userid)) {
                Map<String, Object> qmap = new HashMap<>();
                qmap.put("USERID", userid);
                List<SysUserOrgDo> userorgs = (List<SysUserOrgDo>) sysUserOrgService.listByMap(qmap);
                if (userorgs != null && userorgs.size() > 0) {
                    return pointCheckDao.pointHasCheckSUlist(pointCheckVo.getPage(), pointCheckVo.getParameter().getCheckstatus(), null, userorgs.get(0).getOrgid(), null, null, null, null, pointCheckVo.getParameter().getCheckitemid());
                } else {
                    return pointCheckDao.pointHasCheckSUlist(pointCheckVo.getPage(), pointCheckVo.getParameter().getCheckstatus(), userid, null, null, null, null, null, pointCheckVo.getParameter().getCheckitemid());
                }
            }
        } else {
            // 待点检
            // 根据当前时间获取查询的班次
            String shift = null;
            int hour = DateUtil.hour(new Date(), true);
            int minute = DateUtil.minute(new Date());
            if (hour >= 0 && hour < 8) {
                // 0点-8点 夜班
                shift = "20";
            } else if (hour >= 8 && hour < 16) {
                // 8点-16点 夜班
                shift = "30";
            } else if (hour >= 16 && hour < 24) {
                // 16点-24点 夜班
                shift = "40";
            }

            return pointCheckDao.pointCheckSUlist(pointCheckVo.getPage(), pointCheckVo.getParameter().getCheckstatus(), pointCheckVo.getParameter().getUserid(), shift, pointCheckVo.getParameter().getCheckitemid());
        }
        return null;
    }

    /**
     * 查询未点检列表
     * 近一个月
     *
     * @param pointCheckVo
     * @return
     */
    @Override
    public IPage<PointCheckVo> notPointCheckList(QueryPar<PointCheckVo> pointCheckVo) {
        //默认查最近一个月
        DateTime dt = DateUtil.lastMonth();
        String bg = DateUtil.format(dt, "yyyy-MM-dd");
        String userid = pointCheckVo.getParameter().getUserid();
        if (StringUtils.isNotEmpty(userid)) {
            Map<String, Object> qmap = new HashMap<>();
            qmap.put("USERID", userid);
            List<SysUserOrgDo> userorgs = (List<SysUserOrgDo>) sysUserOrgService.listByMap(qmap);
            if (userorgs != null && userorgs.size() > 0) {
                return pointCheckDao.notPointCheckList(pointCheckVo.getPage(), bg, null, null, userorgs.get(0).getOrgid(), pointCheckVo.getParameter().getCheckitemid());
            } else {
                return pointCheckDao.notPointCheckList(pointCheckVo.getPage(), bg, null, userid, null, pointCheckVo.getParameter().getCheckitemid());
            }
        }
        return null;
    }

    /**
     * 点检详情信息
     *
     * @param pointCheckDo
     * @return
     */
    @Override
    public PointCheckVo ydPointCheckInfo(PointCheckDo pointCheckDo) {
        PointCheckVo pv = pointCheckDao.pointCheckSUInfo(pointCheckDo.getId());
        List<PointCheckItemDo> list = pointCheckItemService.getListByPointCheckId(pv.getId());
        List<PointCheckItemVo> pointCheckItems = new ArrayList<>();
        for (PointCheckItemDo pointCheckItem : list) {
            PointCheckItemVo vo = new PointCheckItemVo();
            String checkItemContentId = pointCheckItem.getCheckitemcontentid();
            CheckItemContentDo cicd = checkItemContentService.getById(checkItemContentId);
            try {
                BeanUtils.copyProperties(vo, pointCheckItem);
                vo.setSourcemanagementid(cicd.getManagement());
                pointCheckItems.add(vo);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        pv.setPointCheckItems(pointCheckItems);
        return pv;
    }

    /**
     * 查询上一班点检信息
     *
     * @param pointCheckId
     * @return
     */
    @Override
    public PointCheckVo queryLastCheckInfo(String pointCheckId) {
        // 上一班点检
        PointCheckVo lastPointCheck = null;
        // 根据同设备ID和创建日期倒序排序
        PointCheckDo pointCheckDo = this.getById(pointCheckId);
        List<PointCheckDo> pointChecks = pointCheckDao.getLastPointChecks(pointCheckDo.getCheckitemid(), pointCheckDo.getShift());
        if (pointChecks != null && pointChecks.size() > 0) {
            PointCheckDo pcdo = pointChecks.get(0);
            // 查询当前班次是否有多次检查
            PointCheckDo pck = new PointCheckDo();
            pck.setCheckitemid(pointCheckDo.getCheckitemid());
            pck.setPointcheckname(pcdo.getPointcheckname());
            Wrapper<PointCheckDo> entity1 = (Wrapper<PointCheckDo>) new QueryWrapper(pck).orderByAsc("CREATEDATE");
            List<PointCheckDo> pcks = this.list(entity1);
            // 如果当前设备当前日期当前班次为多次则取第一次
            if (pcks != null && pcks.size() > 1) {
                pcdo = pcks.get(0);
            }
            lastPointCheck = this.ydPointCheckInfo(pcdo);
        }
        return lastPointCheck;
    }

    /**
     * 点检任务保存
     *
     * @param pointCheckVo
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void pointCheckSave(PointCheckVo pointCheckVo) {
        // 点检任务保存
        this.updateById(pointCheckVo);
        // 点检任务明细保存
        List<PointCheckItemDo> pointCheckItems = new ArrayList<>();
        if (pointCheckVo.getPointCheckItems() != null && pointCheckVo.getPointCheckItems().size() > 0) {
            pointCheckVo.getPointCheckItems().forEach(v -> {
                PointCheckItemDo pointCheckItem = new PointCheckItemDo();
                BeanUtil.copyProperties(v, pointCheckItem);
                pointCheckItems.add(pointCheckItem);
            });
            pointCheckItemService.updateBatchById(pointCheckItems);
            Map<String, Object> map = new HashMap<>();
            map.put("ID", pointCheckVo.getId());
            this.createHiddenDangerTask(map);
        }
    }

    /**
     * 点检保存生成隐患跟踪任务
     *
     * @param map
     */
    public void createHiddenDangerTask(Map<String, Object> map) {
        // 点检主表主键ID
        String pointCheckId = map.get("ID").toString();
        if (StringUtils.isNotEmpty(pointCheckId)) {
            PointCheckDo pointCheck = this.getById(pointCheckId);
            Map<String, Object> itemMap = new HashMap<>();
            itemMap.put("POINTCHECKID", pointCheckId);
            List<PointCheckItemDo> items = (List<PointCheckItemDo>) pointCheckItemService.listByMap(itemMap);
            // 生成隐患跟踪任务
            if (items != null && items.size() > 0) {
                for (PointCheckItemDo v : items) {
                    // 非禁用的和报修关注的检查项不生成任务
                    if (StringUtils.isEmpty(v.getManagement()) || MlConstants.POINT_CHECK_MANAGEMENT_NORMAL.equals(v.getManagement())) {
                        continue;
                    }
                    // 查询是否有相同设备相同检查项未关闭的任务存在
                    logger.info("查询是否有相同设备相同检查项未关闭的任务存在...");
                    Map<String, Object> trackMap = new HashMap<>();
                    trackMap.put("RELATIONID", pointCheck.getCheckitemid() + "-" + v.getCheckitemcontentid());
                    trackMap.put("DANGERSOURCE", MlConstants.DANGER_SOURCE_POINTCHECK);
                    trackMap.put("STATUS", MlConstants.HIDDEN_DANGER_STATUS_NOTCLOSE);
                    logger.info("查询参数：" + pointCheck.getCheckitemid() + "-" + v.getCheckitemcontentid() + ";" + MlConstants.DANGER_SOURCE_POINTCHECK + ";" + MlConstants.HIDDEN_DANGER_STATUS_NOTCLOSE + ";");
                    List<HiddenDangerTrackDo> hiddenDangerTracks = (List<HiddenDangerTrackDo>) hiddenDangerTrackService.listByMap(trackMap);
                    if (hiddenDangerTracks == null || hiddenDangerTracks.size() == 0) {
                        logger.info("创建跟踪任务...");
                        createTask(pointCheck, v);
                    }

                    /*if(hiddenDangerTracks != null && hiddenDangerTracks.size()>0){
                        // 如存在未关闭的当前检查项的隐患跟踪则无需创建跟踪任务
                        Boolean normal = true;
                        for(HiddenDangerTrackDo hiddenDangerTrack:hiddenDangerTracks){
                            // 任务未关闭
                            if(!hiddenDangerTrack.getStatus().equals(MlConstants.HIDDEN_DANGER_STATUS_HASCLOSE)){
                                normal = false;
                            }
                        }
                        if(normal){
                            createTask(pointCheck,v);
                        }
                    }else{
                        createTask(pointCheck,v);
                    }*/
                }
                ;
            }
        }
    }

    /**
     * 根据检查内容生成隐患跟踪
     *
     * @param pointCheck
     * @param item
     */
    private void createTask(PointCheckDo pointCheck, PointCheckItemDo item) {
        HiddenDangerTrackDo hiddenDangerTrack = new HiddenDangerTrackDo();
        // 非正常的处置需要生成跟踪任务
        if (StringUtils.isNotEmpty(item.getManagement()) && !item.getManagement().equals(MlConstants.POINT_CHECK_MANAGEMENT_NORMAL)) {
            hiddenDangerTrack.setId(SecurityUtil.getUUID());
            hiddenDangerTrack.setDangersource(MlConstants.DANGER_SOURCE_POINTCHECK);
            hiddenDangerTrack.setRelationid(pointCheck.getCheckitemid() + "-" + item.getCheckitemcontentid());
            hiddenDangerTrack.setFinduser(pointCheck.getCheckuserid());
            hiddenDangerTrack.setFindusername(pointCheck.getCheckusername());
            hiddenDangerTrack.setFindtime(pointCheck.getChecktime());
            hiddenDangerTrack.setTrackusername(item.getTrackuser());
            hiddenDangerTrack.setTrackuserid(item.getTrackuserid());
            hiddenDangerTrack.setFirsttrackuserid(item.getTrackuserid());
            hiddenDangerTrack.setFirsttrackusername(item.getTrackuser());
            hiddenDangerTrack.setSafetypromoter(pointCheck.getSafeuser());
            hiddenDangerTrack.setSafetypromoterid(pointCheck.getSafeuserid());
            // 限整改日期
            if (pointCheck.getChecktime() != null) {
                hiddenDangerTrack.setRectificationdate(DateUtil.offsetDay(pointCheck.getChecktime(), 7));
            }
            CheckItemsDo checkItemsDo = checkItemsService.getById(pointCheck.getCheckitemid());
            if (checkItemsDo != null) {
                // 隐患内容  取【工段】+【设备编号】+【设备名称】+【班组】+【检查内容】+“ 对应备注。”
                StringBuilder hiddendangercontent = new StringBuilder();
                if (StringUtils.isNotEmpty(checkItemsDo.getChargeorgname())) {
                    hiddendangercontent.append("【").append(checkItemsDo.getChargeorgname()).append("】");
                }
                hiddendangercontent.append("【").append(checkItemsDo.getCheckitemcode()).append("】")
                        .append("【").append(checkItemsDo.getCheckitemname()).append("】")
                        .append("【").append(commonDictService.getDictNameByValue("check-shift", pointCheck.getShift())).append("】");
                if (item.getCheckcontent() != null) {
                    hiddendangercontent.append("【").append(item.getCheckcontent()).append("】");
                }
                // 处置
                if (StringUtils.isNotEmpty(item.getManagement())) {
                    if (MlConstants.POINT_CHECK_MANAGEMENT_NORMAL.equals(item.getManagement())) {
                        hiddendangercontent.append("【正常】");
                    } else if (MlConstants.POINT_CHECK_MANAGEMENT_DISABLE.equals(item.getManagement())) {
                        hiddendangercontent.append("【禁用】");
                    } else if (MlConstants.POINT_CHECK_MANAGEMENT_REPAIR.equals(item.getManagement())) {
                        hiddendangercontent.append("【报修关注】");
                    }
                }
                if (item.getRemark() != null) {
                    hiddendangercontent.append(" " + item.getRemark());
                }
                hiddenDangerTrack.setHiddendangercontent(hiddendangercontent.toString());
                // 任务工段
                hiddenDangerTrack.setDangerworkpark(pointCheck.getWorkshopid());
                hiddenDangerTrack.setDangerworkparkname(pointCheck.getWorkshopname());
            }
            // 指派跟踪人取点检人的所属工段的工段主管
//            if(StringUtils.isNotEmpty(pointCheck.getCheckuserid())){
//                List<Map<String,Object>> umap = pointCheckDao.getGdzgByUserId(pointCheck.getCheckuserid());
//                if(umap != null && umap.size()>0){
//                    hiddenDangerTrack.setTrackuserid(umap.get(0).getOrDefault("USERID","").toString());
//                    hiddenDangerTrack.setTrackusername(umap.get(0).getOrDefault("USERNAME","").toString());
//                    // 设置最初指派跟踪人
//                    hiddenDangerTrack.setFirsttrackuserid(umap.get(0).getOrDefault("USERID","").toString());
//                    hiddenDangerTrack.setFirsttrackusername(umap.get(0).getOrDefault("USERNAME","").toString());
//                }
//            }
            // 默认待关闭
            hiddenDangerTrack.setStatus(MlConstants.HIDDEN_DANGER_STATUS_NOTCLOSE);
            hiddenDangerTrack.setSource("1");
            hiddenDangerTrack.setCheckphoto(pointCheck.getCheckphoto());
            // 隐患类型默认为一般
            hiddenDangerTrack.setHiddendangertype(MlConstants.HIDDEN_DANGER_TYPE_NORMAL);

            String code = streamCodeGeneration("asp_hidden_danger_track_CODE_sb",
                    "@{date:yyyyMMdd}@{serialNumber:#000000}", "date:yyyy", pointCheck.getTenantid());
            hiddenDangerTrack.setTenantid(pointCheck.getTenantid());
            hiddenDangerTrack.setCode(code);
            hiddenDangerTrackService.save(hiddenDangerTrack);
        }
    }

    /**
     * 定时任务，点检延期提醒
     */
    public void pintCheckDelayReminder() {
        // 需要邮件提醒的点检
        Map<String, List<PointCheckVo>> map = new HashMap<>();
        // 查询状态为已延期的点检
        List<PointCheckVo> pointCheckVos = pointCheckDao.getDelays();
        if (pointCheckVos != null && pointCheckVos.size() > 0) {
            for (PointCheckVo pointCheck : pointCheckVos) {
                String orgid = pointCheck.getChargeorgid();
                if (StringUtils.isNotEmpty(orgid)) {
                    String[] gdOrgids = orgid.split("/");
                    List<Map<String, Object>> listMap = pointCheckDao.getGdzgByOrgId(gdOrgids[gdOrgids.length - 1]);
                    // 接收人拆分所有待提醒的点检
                    if (listMap != null && listMap.size() > 0) {
                        for (Map<String, Object> lmap : listMap) {
                            String userid = lmap.get("USERID").toString();
                            if (StringUtils.isNotEmpty(userid)) {
                                if (map.containsKey(userid)) {
                                    map.get(userid).add(pointCheck);
                                } else {
                                    List<PointCheckVo> toWarns = new ArrayList<>();
                                    toWarns.add(pointCheck);
                                    map.put(userid, toWarns);
                                }
                            }
                        }
                    }
                }

                // 点检延期自动关闭,并设置已延期
                PointCheckDo pointCheckDo = new PointCheckDo();
                pointCheckDo.setId(pointCheck.getId());
                pointCheckDo.setCheckstatus(MlConstants.POINT_CHECK_STATUS_HAS);
                pointCheckDo.setCheckwarnstatus(MlConstants.POINTCEHCK_WARNSTATUS_DELAY);
                this.updateById(pointCheckDo);
            }

            // 邮件发送
            if (map.size() > 0) {
                for (String userid : map.keySet()) {
                    List<PointCheckVo> toWarns = map.get(userid);
                    SysUserDo userdo = sysUserService.getById(userid);
                    if (StringUtils.isNotEmpty(userdo.getEmail())) {
                        MailDo mail = new MailDo();
                        mail.setSubject("点检延期提醒");
                        String[] reMails = {userdo.getEmail()};
                        mail.setReceiveEmail(reMails);
                        StringBuilder mailContent = new StringBuilder("您好！您有如下点检任务未如期执行，请注意及时跟进处理，谢谢。\n");
                        if (toWarns != null && toWarns.size() > 0) {
                            for (PointCheckVo pointCheckVo : toWarns) {
                                mailContent.append("设备编号：");
                                if (StringUtils.isNotEmpty(pointCheckVo.getCheckitemcode())) {
                                    mailContent.append(pointCheckVo.getCheckitemcode());
                                }
                                mailContent.append("，");
                                mailContent.append("设备名称：");
                                if (StringUtils.isNotEmpty(pointCheckVo.getCheckitemname())) {
                                    mailContent.append(pointCheckVo.getCheckitemname());
                                }
                                mailContent.append("，");
                                mailContent.append("日期：");
                                if (pointCheckVo.getCreatedate() != null) {
                                    mailContent.append(DateUtil.format(pointCheckVo.getCreatedate(), "yyyy-MM-dd"));
                                }
                                mailContent.append("，");
                                mailContent.append("班次：");
                                if (StringUtils.isNotEmpty(pointCheckVo.getShiftname())) {
                                    mailContent.append(pointCheckVo.getShiftname());
                                }
                                mailContent.append("；\n");
                            }
                        }
                        mailContent.append("详见智能安全监控平台：http://192.168.0.205:8000");
                        mail.setContent(mailContent.toString());
                        // 邮件发送服务调用
                        sysConfigFeignService.sendTextMail(mail);
                    }
                }
            }
        }
    }


    /**
     * 备用设备待点检
     *
     * @param pointCheckVo
     * @return
     */
    @Override
    public IPage<PointCheckVo> sparePointCheckList(QueryPar<PointCheckVo> pointCheckVo) {

        if (MlConstants.POINT_CHECK_STATUS_HAS.equals(pointCheckVo.getParameter().getCheckstatus())) {
            //已点检
            return pointCheckDao.sparePointHasCheckSUlist(pointCheckVo.getPage(), pointCheckVo.getParameter().getCheckstatus(), pointCheckVo.getParameter().getCheckitemid());
        } else if (MlConstants.POINT_CHECK_STATUS_WAIT.equals(pointCheckVo.getParameter().getCheckstatus())) {
            //待点检
            String shift = null;
            int hour = DateUtil.hour(new Date(), true);
            int minute = DateUtil.minute(new Date());
            if (hour >= 0 && hour < 8) {
                // 0点-8点 夜班
                shift = "20";
            } else if (hour >= 8 && hour < 16) {
                // 8点-16点 白班
                shift = "30";
            } else if (hour >= 16 && hour < 24) {
                // 16点-24点 中班
                shift = "40";
            }
            return pointCheckDao.sparePointCheckSUlist(pointCheckVo.getPage(), pointCheckVo.getParameter().getCheckstatus(), shift, pointCheckVo.getParameter().getCheckitemid());
        } else {
            //未点检
            //默认查最近一个月
            DateTime dt = DateUtil.lastMonth();
            String bg = DateUtil.format(dt, "yyyy-MM-dd");
            return pointCheckDao.spareNotPointCheckList(pointCheckVo.getPage(), bg, null, pointCheckVo.getParameter().getCheckitemid());
        }

    }


}
