package com.testor.module.safeCheck.service.impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.testor.biz.sys.org.model.domain.SysOrg;
import com.testor.biz.sys.user.model.domain.SysUser;
import com.testor.biz.sys.user.service.SysUserService;
import com.testor.common.util.CheckResultStatusEnum;
import com.testor.common.util.CheckTaskStatusEnum;
import com.testor.common.util.DateUtil;
import com.testor.module.safeCheck.dao.TSafeHazardCheckTaskDao;
import com.testor.module.safeCheck.model.domain.TSafeHazardCheckPeople;
import com.testor.module.safeCheck.model.domain.TSafeHazardCheckPlan;
import com.testor.module.safeCheck.model.domain.TSafeHazardCheckResult;
import com.testor.module.safeCheck.model.domain.TSafeHazardCheckTask;
import com.testor.module.safeCheck.model.dto.TSafeHazardCheckDelayParam;
import com.testor.module.safeCheck.model.dto.TSafeHazardCheckResultParam;
import com.testor.module.safeCheck.model.dto.TSafeHazardCheckTaskParam;
import com.testor.module.safeCheck.model.vo.SafeHazardCheckDelayVO;
import com.testor.module.safeCheck.model.vo.SafeHazardCheckResultVO;
import com.testor.module.safeCheck.model.vo.SafeHazardCheckTaskListVO;
import com.testor.module.safeCheck.model.vo.SafeHazardCheckTaskVO;
import com.testor.module.safeCheck.service.*;
import com.testor.module.sys.service.TOrgService;
import com.testor.xxl.job.task.util.CronUtil;
import com.tongtech.tfw.backend.common.biz.constants.BizConstants;
import com.tongtech.tfw.backend.common.biz.models.BaseResponse;
import com.tongtech.tfw.backend.common.biz.models.BaseResponseList;
import com.tongtech.tfw.backend.common.constants.enumeration.BaseStatusEnum;
import com.tongtech.tfw.backend.common.models.supers.SuperServiceImpl;
import com.tongtech.tfw.backend.core.helper.StringHelper;
import com.tongtech.tfw.backend.core.helper.bean.BeanHelper;
import com.tongtech.tfw.workflow.service.TfwProcessInsService;
import com.tongtech.tfw.workflow.service.dto.ProcessInsStartParams;
import com.tongtech.tfw.workflow.service.dto.ProcessInsStartResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 巡检任务Service业务层处理
 * 
 * @author testor-framework
 * @date 2022-08-04 11:07:59
 */
@Slf4j
@Service
public class TSafeHazardCheckTaskServiceImpl extends SuperServiceImpl<TSafeHazardCheckTaskDao, TSafeHazardCheckTask> implements TSafeHazardCheckTaskService
{
    @Autowired(required = false)
    private TSafeHazardCheckTaskDao tSafeHazardCheckTaskDao;

    @Resource
    private TSafeHazardCheckPeopleService tSafeHazardCheckPeopleService;

    @Resource
    private TSafeHazardCheckPlanService tSafeHazardCheckPlanService;

    @Resource
    private TSafeHazardCheckResultService tSafeHazardCheckResultService;

    @Resource
    private TSafeHazardCheckDelayService tSafeHazardCheckDelayService;

    @Autowired
    private TfwProcessInsService tfwProcessInsService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private TOrgService tOrgService;

    @Override
    @Transactional
    public TSafeHazardCheckTask generateCheckTask(String checkPeopleId) {
        System.out.println("生成任务逻辑 待续..."+checkPeopleId);
        if(StrUtil.isBlank(checkPeopleId)) {
            return null;
        }
        TSafeHazardCheckPeople checkPeople = tSafeHazardCheckPeopleService.getById(checkPeopleId);

        TSafeHazardCheckPlan checkPlan = tSafeHazardCheckPlanService.getById(checkPeople.getPlanId());

        TSafeHazardCheckTask safeHazardCheckTask = new TSafeHazardCheckTask();
        safeHazardCheckTask.setPlanId(checkPlan.getId());
        safeHazardCheckTask.setPeopleId(checkPeopleId);
        safeHazardCheckTask.setUserId(checkPeople.getUserId());
        safeHazardCheckTask.setOrgId(checkPlan.getOrgId());
        safeHazardCheckTask.setCheckedOrgId(checkPlan.getCheckedOrgId());
        safeHazardCheckTask.setName(checkPlan.getName());
        safeHazardCheckTask.setCheckTypeId(checkPeople.getCheckTypeId());

        // Long advanceHour = checkPlan.getAdvanceHour();
        // 任务时间
        if(!StrUtil.isBlank(checkPeople.getStartCronExpression())) {
            ZonedDateTime startZonedDateTime = CronUtil.calculateTime(checkPeople.getStartCronExpression(), 2); // 上次次执行时间
            ZonedDateTime endZonedDateTime = CronUtil.calculateTime(checkPeople.getEndCronExpression(), 2); // 上次次执行时间
            if(startZonedDateTime != null) {
                LocalDateTime startDate= startZonedDateTime.toLocalDateTime();
                safeHazardCheckTask.setStartDate(DateUtil.localDateTimeToDate(startDate));
            }

            if(endZonedDateTime != null) {
                LocalDateTime endDate= endZonedDateTime.toLocalDateTime();
                safeHazardCheckTask.setEndDate(DateUtil.localDateTimeToDate(endDate));
                safeHazardCheckTask.setInitialEndDate(DateUtil.localDateTimeToDate(endDate));
            }

            safeHazardCheckTask.setTaskStatus(CheckTaskStatusEnum.running.getCode());
            safeHazardCheckTask.setIsOverdue("0");

            tSafeHazardCheckTaskDao.insert(safeHazardCheckTask);

            // 创建 巡检任务结果 及 结果明细
            if(!tSafeHazardCheckResultService.createByTask(safeHazardCheckTask.getId(), checkPlan.getId())){
                throw new RuntimeException("巡检结果创建失败");
            }

            // todo 创建 任务流程
            // 计划创建者
            SysUser curUser = sysUserService.getById(checkPlan.getCreateBy());
            ProcessInsStartParams processInsStartParams = new ProcessInsStartParams();
            processInsStartParams.setUserId(curUser.getUserId());
            processInsStartParams.setOrgId(curUser.getOrgId());
            processInsStartParams.setBizKey(safeHazardCheckTask.getId());
            processInsStartParams.setProcessDefinitionKey("checkTaskBill");
            Map<String, Object> varMap = new HashMap<>();
            varMap.put("processStatus", "3");
            varMap.put("checkUser", safeHazardCheckTask.getUserId());
            processInsStartParams.setVariables(varMap);
            ProcessInsStartResult processInsStartResult = tfwProcessInsService.startProcessInsByKey(processInsStartParams);
           // processInsStartResult.getCode();
            // 更新 task：写入流程id
            safeHazardCheckTask.setProcessId(processInsStartResult.getCode());
            updateById(safeHazardCheckTask);

            return safeHazardCheckTask;
        }

        return null;
    }

    @Override
    public BaseResponseList<SafeHazardCheckTaskListVO> listPage(TSafeHazardCheckTaskParam param) {

        BaseResponseList<SafeHazardCheckTaskListVO> baseResponseList=new BaseResponseList<>();

        Long page =
                StringHelper.isEmpty(param.getPage()) ? BizConstants.PAGE : Long.valueOf(param.getPage());
        Long limit =
                StringHelper.isEmpty(param.getLimit()) ? BizConstants.LIMIT : Long.valueOf(param.getLimit());
        Page<SafeHazardCheckTaskListVO> resultPage = new Page<>(page, limit);
        IPage<SafeHazardCheckTaskListVO> iPage = tSafeHazardCheckTaskDao.listPage(resultPage, param);

        List<SafeHazardCheckTaskListVO> vOList = iPage.getRecords();
        vOList.forEach(item -> {
            SysOrg regionalCompany = tOrgService.getRegionalCompany(item.getOrgId());
            if (regionalCompany != null) {
                item.setBusinessOrgName(regionalCompany.getOrgName());
            }
        });
        if (vOList == null || vOList.size() == 0) {
            baseResponseList.setData(iPage.getRecords());
            baseResponseList.setTotal(iPage.getTotal());
            return baseResponseList;
        }

        baseResponseList.setData(vOList);
        baseResponseList.setTotal(iPage.getTotal());
        return baseResponseList;
    }

    /**
     *
     * @return 0-未开始；1-进行中
     */
    public Integer calTaskStatus(LocalDateTime startDate, LocalDateTime endDate) {

        if(startDate == null) {
            return null;
        }

        LocalDateTime nowDate = LocalDateTime.now();
        long offsetDiffVal = LocalDateTimeUtil.between(nowDate, startDate, ChronoUnit.SECONDS);
        if(offsetDiffVal > 0) {
            return 0;
        }

//        long endDiffVal = LocalDateTimeUtil.between(nowDate, endDate, ChronoUnit.SECONDS);
//        if(endDiffVal >= 0) {
//            return 1;
//        }
//        return null;

        return 1;
    }

    /**
     * 巡检排查任务状态更改任务: 未开始 -> 进行中
     */
    @Override
    public Boolean changeCheckTaskStatus(String checkTaskId){
        UpdateWrapper<TSafeHazardCheckTask> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", checkTaskId);
        updateWrapper.set("task_status", CheckTaskStatusEnum.running.getCode());
        int result = tSafeHazardCheckTaskDao.update(null, updateWrapper);

        return result == 1 ? true:false;
    }

    @Override
    public SafeHazardCheckTaskVO findById(String taskId) {
        if(StrUtil.isBlank(taskId)) {
            return null;
        }
        TSafeHazardCheckTaskParam param = new TSafeHazardCheckTaskParam();
        param.setId(taskId);
        Page<SafeHazardCheckTaskListVO> resultPage = new Page<>(1, 1);
        IPage<SafeHazardCheckTaskListVO> iPage = tSafeHazardCheckTaskDao.listPage(resultPage, param);
        List<SafeHazardCheckTaskListVO> vOList = iPage.getRecords();
        if (vOList == null || vOList.size() == 0) {
            return null;
        }
        SafeHazardCheckTaskVO taskVO = BeanHelper.beanToBean(vOList.get(0), SafeHazardCheckTaskVO.class);

        // 排查对象结果
        List<SafeHazardCheckResultVO> resultVOList = tSafeHazardCheckResultService.listByTask(taskId);
        taskVO.setCheckResultVOList(resultVOList);

        //  延期申请
        List<SafeHazardCheckDelayVO> checkDelayVOList = tSafeHazardCheckDelayService.listVOByTask(taskId);
        taskVO.setCheckDelayList(checkDelayVOList);

        TSafeHazardCheckDelayParam delayParam = new TSafeHazardCheckDelayParam();
        delayParam.setStatus(BizConstants.STATUS_ENABLE);
        delayParam.setTaskId(taskId);
        delayParam.setApprovalStatus(2);
        List<SafeHazardCheckDelayVO> isDelayVOList = tSafeHazardCheckDelayService.listVOByParam(delayParam);
        if(isDelayVOList != null && isDelayVOList.size() > 0) {
            taskVO.setIsDelaying(1);
        } else {
            taskVO.setIsDelaying(0);
        }
        return taskVO;
    }

    /**
     * 提交 完成任务
     * @param taskId
     * @return
     */
    @Override
    public BaseResponse completeTask(String checkTaskId, String taskId) {

        BaseResponse baseResponse = new BaseResponse<>();

        if(StrUtil.isBlank(checkTaskId)){
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("参数缺失");
            return baseResponse;
        }
        TSafeHazardCheckTask task = getById(checkTaskId);
        List<Integer> resultStatusList = new ArrayList<>();
        resultStatusList.add(CheckResultStatusEnum.nostart.getCode());
        resultStatusList.add(CheckResultStatusEnum.running.getCode());
        TSafeHazardCheckResultParam safeHazardCheckResultParam = new TSafeHazardCheckResultParam();
        safeHazardCheckResultParam.setStatus(BizConstants.STATUS_ENABLE);
        safeHazardCheckResultParam.setTaskId(checkTaskId);
        safeHazardCheckResultParam.setResultStatusList(resultStatusList);
        List<TSafeHazardCheckResult> resultList = tSafeHazardCheckResultService.listEntity(safeHazardCheckResultParam);
        if(resultList != null && resultList.size() > 0) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("存在未完成巡检项，无法提交完成任务！");
            return baseResponse;
        }

        LocalDateTime nowDate = LocalDateTimeUtil.now();
        task.setTaskStatus(CheckTaskStatusEnum.complete.getCode());
        task.setCompleteDate(DateUtil.localDateTimeToDate(nowDate));
        long betVal = LocalDateTimeUtil.between(DateUtil.dateToLocalDateTime(task.getEndDate()), nowDate, ChronoUnit.SECONDS);
        if(betVal > 0) {
            task.setIsOverdue("1");
        } else {
            task.setIsOverdue("0");
        }
        updateById(task);
        baseResponse.setCode(BaseStatusEnum.SUCCESS.code());

        // 巡检任务 检查完成 更改 流程状态
//        UserInfo curUser = ContextUtils.getLoginUser();
//        TaskCompleteParams taskCompleteParams = new TaskCompleteParams();
//        taskCompleteParams.setUserId(curUser.getUserId());
//        taskCompleteParams.setOrgId(curUser.getOrgId());
//        taskCompleteParams.setTaskId(taskId); // 审批流程对应任务id
//        taskCompleteParams.setBizId(checkTaskId); // 业务数据id
//        Map<String, Object> varMap = new HashMap<>();
//        varMap.put("processStatus", "5");
//        varMap.put("pass", true);
//        taskCompleteParams.setVars(varMap);
//        TaskServiceResult taskServiceResult = tfwTaskService.completeTask(taskCompleteParams);
//        log.info("*****巡检任务'{}'提交完成 关联的审批流程完成情况：{}", task.getId(), JSON.toJSONString(taskServiceResult));
//
        return baseResponse;
    }

}
