package com.trade.admin.workflow.service.impl;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.trade.admin.system.domain.entity.SysUser;
import com.trade.admin.system.security.utils.SecurityUtils;
import com.trade.admin.system.service.ISysUserService;
import com.trade.admin.workflow.domain.BusinessProcessingLog;
import com.trade.admin.workflow.dto.BusinessProcessingLogDetailVo;
import com.trade.admin.workflow.dto.BusinessProcessingLogVo;
import com.trade.admin.workflow.mapper.BusinessProcessingLogMapper;
import com.trade.admin.workflow.service.BusinessProcessingLogService;
import com.trade.admin.workflow.util.FlowableConstantUtil;
import com.trade.common.utils.DateUtils;
import com.trade.common.validate.ValidatorGroup;
import com.trade.common.validate.ValidatorUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;


@Service
public class BusinessProcessingLogServiceImpl extends ServiceImpl<BusinessProcessingLogMapper, BusinessProcessingLog> implements BusinessProcessingLogService {
    @Autowired
    private BusinessProcessingLogMapper processingLogMapper;
    @Autowired
    private ISysUserService sysUserService;

    @Override
    @Transactional
    public BusinessProcessingLog add(BusinessProcessingLog processingLog) {
        ValidatorUtil.validator(ValidatorGroup.ValidatorType.ADD, processingLog);
        String userName = SecurityUtils.getUserNickName();
        if (StrUtil.isNotEmpty(userName)) {
            processingLog.setCreateBy(userName);
        } else {
            processingLog.setCreateBy("admin");
        }
        processingLogMapper.add(processingLog);
        return processingLogMapper.get(processingLog.getId());
    }

    @Override
    public BusinessProcessingLog get(Long id) {
        return processingLogMapper.get(id);
    }

    @Override
    @Transactional
    public Boolean update(BusinessProcessingLog processingLog) {
        ValidatorUtil.validator(ValidatorGroup.ValidatorType.UPDATE, processingLog);
        if (StrUtil.isEmpty(processingLog.getUpdateBy())) {
            processingLog.setUpdateBy(SecurityUtils.getUserNickName());
        }
        return processingLogMapper.update(processingLog) == 1;
    }

    @Override
    public List<BusinessProcessingLogDetailVo> findByBusiness(Long businessKey, String businessType) {

        List<String> historicTaskIds = processingLogMapper.findTaskByBusiness(businessKey, businessType);
        if (CollUtil.isNotEmpty(historicTaskIds)) {
            List<BusinessProcessingLogDetailVo> businessLogs = new ArrayList<>();
            for (String historicTaskId : historicTaskIds) {
                List<BusinessProcessingLog> taskProcessingLogs = processingLogMapper.findLogsByBusiness(businessKey,
                        businessType, historicTaskId, null, null);
                if (CollUtil.isNotEmpty(taskProcessingLogs)) {
                    List<BusinessProcessingLogVo> voList = new ArrayList<>();
                    String taskName = null;
                    for (BusinessProcessingLog log : taskProcessingLogs) {
                        taskName = log.getTaskName();
                        BusinessProcessingLogVo vo = new BusinessProcessingLogVo();
                        if (null != log.getAssignee()) {
                            SysUser assign = sysUserService.selectUserById(log.getAssignee().getId());
                            vo.setAssigneeName(assign != null ? assign.getUserName() : "");
                        }
                        vo.setAssigneeTypeName(FlowableConstantUtil.assigneeType.get(log.getAssigneeType()));
                        // 上午、下午开始时间换算
                        String startTimeStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, log.getStartTime());
                        String endTimeStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, log.getEndTime());
                        vo.setStartTime(startTimeStr);
                        vo.setEndTime(endTimeStr);
                        if (StrUtil.isNotEmpty(log.getStatus())) {
                            vo.setStatus(log.getStatus());
                        }
                        if (null != log.getOverdueDays() && log.getOverdueDays() > 0) {
                            vo.setOverdue("逾期" + log.getOverdueDays() + (log.getWorkingDay() ? "个工作日" : "个自然日"));
                        }
                        voList.add(vo);
                    }
                    businessLogs.add(new BusinessProcessingLogDetailVo(taskName, voList));
                }
            }

            return businessLogs;
        }
        return null;
    }

    @Override
    public BusinessProcessingLog getLatestByTask(Long businessKey, String businessType, String historicTaskId,
                                                 String assigneeType) {
        List<BusinessProcessingLog> logs = processingLogMapper.findLogsByBusiness(businessKey, businessType,
                historicTaskId, assigneeType, true);
        if (CollUtil.isNotEmpty(logs)) {
            return logs.get(0);
        }
        return null;
    }

    @Override
    public List<BusinessProcessingLog> findCompletedByBusiness(Long businessKey, String businessType) {
        return processingLogMapper.findCompletedByBusiness(businessKey, businessType);
    }

    @Override
    public List<String> findPendingTaskByBusiness(Long businessKey, String businessType) {
        return processingLogMapper.findPendingTaskByBusiness(businessKey, businessType);
    }

    @Override
    public List<BusinessProcessingLog> findPendingByBusinessKeys(String taskDefKey, String businessType,
                                                                 List<Long> businessKeys, String assigneeType) {
        List<String> taskIds = processingLogMapper.findPendingTaskByBusinessKeys(taskDefKey, businessType, businessKeys,
                assigneeType);
        List<BusinessProcessingLog> logs = new ArrayList<>();
        if (CollUtil.isNotEmpty(taskIds)) {
            for (String taskId : taskIds) {
                BusinessProcessingLog log = processingLogMapper.getPendingByTaskId(taskId, assigneeType);
                if (null != log && null == log.getFormBusinessId() && null == log.getEndTime()) {
                    logs.add(log);
                }
            }
            return logs;
        }
        return logs;// 不建议返回NULL，这里引用易产生空指针异常
    }

    @Override
    public BusinessProcessingLog findByHistoricTaskId(String taskId) {
        return processingLogMapper.findByHistoricTaskId(taskId);
    }

    @Override
    public void updateAssigneeId(BusinessProcessingLog processingLog) {
        processingLogMapper.updateAssigneeId(processingLog);
    }

    @Override
    public BusinessProcessingLog getByBusinessTypeBusinessKey(String businessType, Long busnessKey) {
        return processingLogMapper.getByBusinessTypeBusinessKey(busnessKey, businessType);
    }

    @Override
    public BusinessProcessingLog findLatestByTaskDefKey(String taskDefKey, String businessType, Long businessKey) {
        return processingLogMapper.findLatestByTaskDefKey(taskDefKey, businessType, businessKey);
    }

    @Override
    public BusinessProcessingLog getLastByBusinessKeyBusinessTypeTaskName(Long businessKey, String businessType, String taskName) {
        return processingLogMapper.getLastByBusinessKeyBusinessTypeTaskName(businessKey, businessType, taskName);
    }

}
