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.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.testor.common.util.CheckTaskStatusEnum;
import com.testor.common.util.DateUtil;
import com.testor.module.safeCheck.dao.TSafeHazardCheckDelayDao;
import com.testor.module.safeCheck.dao.TSafeHazardCheckResultDao;
import com.testor.module.safeCheck.dao.TSafeHazardCheckTaskDao;
import com.testor.module.safeCheck.model.domain.TSafeHazardCheckDelay;
import com.testor.module.safeCheck.model.domain.TSafeHazardCheckTask;
import com.testor.module.safeCheck.model.dto.TSafeHazardCheckDelayParam;
import com.testor.module.safeCheck.model.dto.TSafeHazardCheckTaskParam;
import com.testor.module.safeCheck.model.vo.*;
import com.testor.module.safeCheck.service.TSafeHazardCheckDelayService;
import com.testor.module.safeCheck.service.TSafeHazardCheckTaskService;
import com.tongtech.tfw.backend.common.biz.constants.BizConstants;
import com.tongtech.tfw.backend.common.biz.models.BaseResponse;
import com.tongtech.tfw.backend.common.constants.enumeration.BaseStatusEnum;
import com.tongtech.tfw.backend.common.context.ContextUtils;
import com.tongtech.tfw.backend.common.models.supers.SuperServiceImpl;
import com.tongtech.tfw.backend.common.models.sys.UserInfo;
import com.tongtech.tfw.backend.core.helper.ObjectHelper;
import com.tongtech.tfw.backend.core.helper.StringHelper;
import com.tongtech.tfw.backend.core.helper.bean.BeanHelper;
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.temporal.ChronoUnit;
import java.util.List;

/**
 * 巡检任务延期申请Service业务层处理
 *
 * @author testor-framework
 * @date 2022-08-04 11:07:09
 */
@Service
public class TSafeHazardCheckDelayServiceImpl extends SuperServiceImpl<TSafeHazardCheckDelayDao, TSafeHazardCheckDelay> implements TSafeHazardCheckDelayService {
    @Autowired(required = false)
    private TSafeHazardCheckDelayDao tSafeHazardCheckDelayDao;

    @Resource
    private TSafeHazardCheckTaskService tSafeHazardCheckTaskService;

    @Resource
    private TSafeHazardCheckTaskDao tSafeHazardCheckTaskDao;

    @Resource
    private TSafeHazardCheckResultDao tSafeHazardCheckResultDao;

    @Override
    @Transactional
    public BaseResponse editCheckDelay(TSafeHazardCheckDelay checkDelay) {
        BaseResponse baseResponse = new BaseResponse<>();

        UserInfo curUser = ContextUtils.getLoginUser();
        if (StrUtil.isBlank(curUser.getOrgId())) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("用户信息错误");
            return baseResponse;
        }

        LocalDateTime delayDate = DateUtil.dateToLocalDateTime(checkDelay.getDelayCheckDate());
        String delayReason = checkDelay.getReason();
        String taskId = checkDelay.getTaskId();
        if (delayDate == null || StrUtil.isBlank(delayReason) || StrUtil.isBlank(taskId)) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("参数缺失");
            return baseResponse;
        }

        String userId = curUser.getUserId();
        LocalDateTime nowDate = LocalDateTimeUtil.now();

        TSafeHazardCheckTask task = tSafeHazardCheckTaskService.getById(taskId);
        LocalDateTime taskEndDate = DateUtil.dateToLocalDateTime(task.getEndDate());
        if(LocalDateTimeUtil.between(delayDate, taskEndDate, ChronoUnit.SECONDS) > 0){
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("延期时间不能小于原排查限期");
            return baseResponse;
        }

        String dataId = checkDelay.getId();
        if (StrUtil.isBlank(dataId)) { // 新增
            checkDelay.setApplyDate(DateUtil.localDateTimeToDate(nowDate));
            checkDelay.setCreateBy(userId);
            checkDelay.setInitialCheckDate(DateUtil.localDateTimeToDate(taskEndDate));
            checkDelay.setApprovalStatus(2);
            tSafeHazardCheckDelayDao.insert(checkDelay);
            baseResponse.setData(checkDelay);

            task.setTaskStatus(CheckTaskStatusEnum.noapproved.getCode());
            tSafeHazardCheckTaskService.updateById(task);

            return baseResponse;
        }

        TSafeHazardCheckDelay oldDelay = getById(dataId);
        if(!oldDelay.getTaskId().equals(taskId)) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("编辑不能修改所属任务");
            return baseResponse;
        }
        checkDelay.setUpdateBy(userId);
        Integer doResult = tSafeHazardCheckDelayDao.updateById(checkDelay);

        if (doResult == null || doResult != 1) {
            baseResponse.setCode(BaseStatusEnum.UNKNOWN.code());
            baseResponse.setMsg("排查计划编辑失败");
            return baseResponse;
        }

        baseResponse.setData(checkDelay);
        return baseResponse;
    }

    @Transactional
    public BaseResponse approvalCheckDelay(TSafeHazardCheckDelay checkDelay){

        BaseResponse baseResponse = new BaseResponse<>();

        TSafeHazardCheckDelay oldDelay = getById(checkDelay.getId());

        Integer approvalStatus = checkDelay.getApprovalStatus();
        if(approvalStatus == null) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("参数缺失");
            return baseResponse;
        }

        UserInfo curUser = ContextUtils.getLoginUser();
        if (StrUtil.isBlank(curUser.getOrgId())) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("用户信息错误");
            return baseResponse;
        }

        LocalDateTime nowDate = LocalDateTimeUtil.now();
        oldDelay.setApprovalDate(DateUtil.localDateTimeToDate(nowDate));
        oldDelay.setApprovalUserId(curUser.getUserId());
        oldDelay.setApprovalStatus(approvalStatus);
        oldDelay.setApprovalOpinion(checkDelay.getApprovalOpinion());

        // 审批通过 更改任务 限期时间
        TSafeHazardCheckTask task = tSafeHazardCheckTaskService.getById(oldDelay.getTaskId());
        if(approvalStatus == 1) { // 审批通过
            task.setEndDate(oldDelay.getDelayCheckDate());
        }

        updateById(oldDelay);

        // 审批后 更改任务状态
        task.setTaskStatus(CheckTaskStatusEnum.running.getCode());
        tSafeHazardCheckTaskService.updateById(task);

        baseResponse.setCode(BaseStatusEnum.SUCCESS.code());
        return baseResponse;
    }

    @Transactional
    public BaseResponse deleteCheckDelay(String checkDelayId){

        BaseResponse baseResponse = new BaseResponse<>();

        if(StrUtil.isBlank(checkDelayId)) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("参数缺失");
            return baseResponse;
        }

        UserInfo curUser = ContextUtils.getLoginUser();
        LocalDateTime nowDate = LocalDateTimeUtil.now();
        TSafeHazardCheckDelay checkDelay = getById(checkDelayId);

        // 删除申请后 恢复任务状态为 进行中
        TSafeHazardCheckTask task = tSafeHazardCheckTaskService.getById(checkDelay.getTaskId());
        task.setTaskStatus(CheckTaskStatusEnum.running.getCode());

        checkDelay.setStatus(BizConstants.STATUS_DELETE);
        checkDelay.setUpdateDate(DateUtil.localDateTimeToDate(nowDate));
        checkDelay.setUpdateBy(curUser.getUserId());
        updateById(checkDelay);

        tSafeHazardCheckTaskService.updateById(task);

        baseResponse.setCode(BaseStatusEnum.SUCCESS.code());
        return baseResponse;
    }

    @Override
    public List<TSafeHazardCheckDelay> listEntity(TSafeHazardCheckDelayParam param) {
        QueryWrapper<TSafeHazardCheckDelay> queryWrapper=this.createQuery(param);
        List<TSafeHazardCheckDelay> resultList= list(queryWrapper);
        return resultList;
    }

    @Override
    public List<TSafeHazardCheckDelay> listByTask(String taskId){
        TSafeHazardCheckDelayParam param = new TSafeHazardCheckDelayParam();
        param.setStatus(BizConstants.STATUS_ENABLE);
        param.setTaskId(taskId);
        QueryWrapper<TSafeHazardCheckDelay> queryWrapper=this.createQuery(param);
        List<TSafeHazardCheckDelay> resultList= list(queryWrapper);
        return resultList;
    }

    @Override
    public List<SafeHazardCheckDelayVO> listVOByTask(String taskId){
        TSafeHazardCheckDelayParam param = new TSafeHazardCheckDelayParam();
        param.setStatus(BizConstants.STATUS_ENABLE);
        param.setTaskId(taskId);
        List<SafeHazardCheckDelayVO> resultList= listVOByParam(param);
        return resultList;
    }

    @Override
    public List<SafeHazardCheckDelayVO> listVOByParam(TSafeHazardCheckDelayParam param){
        List<SafeHazardCheckDelayVO> checkDelayVOList = tSafeHazardCheckDelayDao.listVOByParam(param);
        return checkDelayVOList;
    }

    @Override
    public SafeHazardCheckTaskDelayVO findById(String delayId) {
        if(StrUtil.isBlank(delayId)) {
            return null;
        }
        TSafeHazardCheckDelayParam delayParam = new TSafeHazardCheckDelayParam();
        delayParam.setId(delayId);
        List<SafeHazardCheckDelayVO> checkDelayVOList = tSafeHazardCheckDelayDao.listVOByParam(delayParam);
        if(checkDelayVOList == null || checkDelayVOList.size() == 0) {
            return null;
        }

        SafeHazardCheckDelayVO delayVO = checkDelayVOList.get(0);
        String taskId = delayVO.getTaskId();
        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);

        SafeHazardCheckTaskDelayVO taskDelayVO = BeanHelper.beanToBean(taskVO, SafeHazardCheckTaskDelayVO.class);
        // 排查对象
        List<SafeHazardCheckResultVO> resultVOList = tSafeHazardCheckResultDao.listByTask(taskId);
        if(resultVOList != null && resultVOList.size() > 0) {
            taskDelayVO.setCheckResultVOList(resultVOList);
        }

        taskDelayVO.setCheckDelay(delayVO);
        return taskDelayVO;
    }



    /* Private Methods */
    /**
     * 列表查询条件及查询参数
     */
    private QueryWrapper<TSafeHazardCheckDelay> createQuery(TSafeHazardCheckDelayParam queryParam){
        QueryWrapper<TSafeHazardCheckDelay> queryWrapper=new QueryWrapper<>();
        if(StringHelper.isNotEmpty(queryParam.getTaskId())){
            queryWrapper.eq(TSafeHazardCheckDelay.TASK_ID,queryParam.getTaskId());
        }
        if(StringHelper.isNotEmpty(queryParam.getApprovalUserId())){
            queryWrapper.eq(TSafeHazardCheckDelay.APPROVAL_USER_ID,queryParam.getApprovalUserId());
        }
        if(ObjectHelper.isNotEmpty(queryParam.getInitialCheckDate())){
            queryWrapper.eq(TSafeHazardCheckDelay.INITIAL_CHECK_DATE,queryParam.getInitialCheckDate());
        }
        if(StringHelper.isNotEmpty(queryParam.getReason())){
            queryWrapper.eq(TSafeHazardCheckDelay.REASON,queryParam.getReason());
        }
        if(StringHelper.isNotEmpty(queryParam.getApprovalOpinion())){
            queryWrapper.eq(TSafeHazardCheckDelay.APPROVAL_OPINION,queryParam.getApprovalOpinion());
        }
        if(ObjectHelper.isNotEmpty(queryParam.getDelayCheckDate())){
            queryWrapper.eq(TSafeHazardCheckDelay.DELAY_CHECK_DATE,queryParam.getDelayCheckDate());
        }
        if(ObjectHelper.isNotEmpty(queryParam.getApplyDate())){
            queryWrapper.eq(TSafeHazardCheckDelay.APPLY_DATE,queryParam.getApplyDate());
        }
        if(ObjectHelper.isNotEmpty(queryParam.getApprovalDate())){
            queryWrapper.eq(TSafeHazardCheckDelay.APPROVAL_DATE,queryParam.getApprovalDate());
        }
        if (StringHelper.isNotEmpty(queryParam.getStatus())) {
            queryWrapper.eq(TSafeHazardCheckDelay.STATUS, queryParam.getStatus());
        } else {
            queryWrapper.ne(TSafeHazardCheckDelay.STATUS, BizConstants.STATUS_DELETE);
        }
        if (StringHelper.isNotEmpty(queryParam.getOrderBy())){
            if(StringHelper.isNotEmpty(queryParam.getOrderType())
                    &&BizConstants.ASC.equals(queryParam.getOrderType())){
                queryWrapper.orderByAsc(queryParam.getOrderBy());
            }else{
                queryWrapper.orderByDesc(queryParam.getOrderBy());
            }
        }else{
            queryWrapper.orderByDesc(TSafeHazardCheckDelay.UPDATE_DATE);
        }
        return queryWrapper;
    }
}
