package com.foreverwin.mesnac.equip.service.impl;

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.foreverwin.mesnac.common.constant.Constants;
import com.foreverwin.mesnac.common.enums.HandleEnum;
import com.foreverwin.mesnac.common.model.InspectionItemDetail;
import com.foreverwin.mesnac.common.service.InspectionItemDetailService;
import com.foreverwin.mesnac.equip.dto.ResourceInspectTaskDto;
import com.foreverwin.mesnac.equip.mapper.ResourceInspectTaskMapper;
import com.foreverwin.mesnac.equip.model.ResourceInspectPlan;
import com.foreverwin.mesnac.equip.model.ResourceInspectTask;
import com.foreverwin.mesnac.equip.model.ResourceInspectTaskParam;
import com.foreverwin.mesnac.equip.model.ResourceInspectTaskSpare;
import com.foreverwin.mesnac.equip.service.ResourceInspectPlanService;
import com.foreverwin.mesnac.equip.service.ResourceInspectTaskParamService;
import com.foreverwin.mesnac.equip.service.ResourceInspectTaskService;
import com.foreverwin.mesnac.equip.service.ResourceInspectTaskSpareService;
import com.foreverwin.modular.core.exception.BusinessException;
import com.foreverwin.modular.core.util.CommonMethods;
import com.foreverwin.modular.core.util.FrontPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 设备检验任务表 服务实现类
 * </p>
 *
 * @author pavel.Liu
 * @since 2021-06-24
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ResourceInspectTaskServiceImpl extends ServiceImpl<ResourceInspectTaskMapper, ResourceInspectTask> implements ResourceInspectTaskService {


    @Autowired
    private ResourceInspectTaskMapper resourceInspectTaskMapper;
    @Autowired
    private ResourceInspectTaskService resourceInspectTaskService;
    @Autowired
    private ResourceInspectPlanService resourceInspectPlanService;
    @Autowired
    private ResourceInspectTaskParamService resourceInspectTaskParamService;
    @Autowired
    private InspectionItemDetailService inspectionItemDetailService;
    @Autowired
    private ResourceInspectTaskSpareService resourceInspectTaskSpareService;

    @Override
    public IPage<ResourceInspectTask> selectPage(FrontPage<ResourceInspectTask> frontPage, ResourceInspectTask resourceInspectTask) {
        QueryWrapper<ResourceInspectTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(resourceInspectTask);
        return super.page(frontPage.getPagePlus(), queryWrapper);
    }

    @Override
    public List<ResourceInspectTask> selectList(ResourceInspectTask resourceInspectTask) {
        QueryWrapper<ResourceInspectTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(resourceInspectTask);
        return super.list(queryWrapper);
    }

    @Override
    public List<ResourceInspectTaskDto> findResourceInspectTaskList(ResourceInspectTaskDto resourceInspectTaskDto) {
        String currentUser = CommonMethods.getUser();
        String site = CommonMethods.getSite();
        String userBo = HandleEnum.USR.getHandle(site, currentUser);
        resourceInspectTaskDto.setCurrentUser(userBo);
        resourceInspectTaskDto.setSite(site);
        List<ResourceInspectTaskDto> list = resourceInspectTaskMapper.findResourceInspectTaskList(resourceInspectTaskDto);
        for (ResourceInspectTaskDto task:list) {
            task.setCycle(getCycle(task));
            task.setCurrentUser(currentUser);
        }
        return list;
    }

    @Override
    public ResourceInspectTask getResourceInspectTaskAll(ResourceInspectTask resourceInspectTask) {
        List<ResourceInspectTask> taskList = resourceInspectTaskService.selectList(resourceInspectTask);
        if (taskList.size() == 1){
            resourceInspectTask = taskList.get(0);
        }else {
            throw BusinessException.build("无法获取任务详情！！！");
        }
        String taskHandle = resourceInspectTask.getHandle();
        String taskStatus = resourceInspectTask.getStatus();
        ResourceInspectTaskParam resourceInspectTaskParam = new ResourceInspectTaskParam();
        resourceInspectTaskParam.setResourceInspectTaskBo(taskHandle);
        if (taskStatus.equals(Constants.INSPECTION_TASK_STATUS_NEW)){
            // 判断数据是否已创建
            List<ResourceInspectTaskParam> taskParams = resourceInspectTaskParamService.selectList(resourceInspectTaskParam);
            // 任务状态为新建时，判断检验项是否更新
            String inspectionItemBo = resourceInspectTask.getInspectionItemBo();
            String resourceInspectPlanBo = resourceInspectTask.getResourceInspectPlanBo();
            ResourceInspectPlan resourceInspectPlan = resourceInspectPlanService.getById(resourceInspectPlanBo);
            String planInspectionItemBo = resourceInspectPlan.getInspectionItemBo();
            // 检验项目清单修改：更新明细表
            if (inspectionItemBo.equals(planInspectionItemBo)){
                // 数据未创建——>全增
                if (taskParams.size() == 0){
                    createAndSaveItemParams(taskHandle,inspectionItemBo);
                }
            }else{
                // 判断数据是否已存在：1、存在，则全删全增；2、不存在，全增
                if ( taskParams.size() > 0 ){
                    resourceInspectTaskParamService.removeAll(resourceInspectTaskParam);
                }
                createAndSaveItemParams(taskHandle,planInspectionItemBo);
            }
        }
        // 新建且检验项清单未变更/非新建状态，直接返回明细清单数据
        HashMap<String, Object> findCondition = new HashMap<>(2);
        findCondition.put(ResourceInspectTaskParam.RESOURCE_INSPECT_TASK_BO,resourceInspectTaskParam.getResourceInspectTaskBo());
        Collection<ResourceInspectTaskParam> taskParams = resourceInspectTaskParamService.listByMap(findCondition);
        List<ResourceInspectTaskParam> itemParamList = new ArrayList<>();
        for (ResourceInspectTaskParam param:taskParams) {
            itemParamList.add(param);
        }
        ResourceInspectTaskSpare resourceInspectTaskSpare = new ResourceInspectTaskSpare();
        resourceInspectTaskSpare.setResourceInspectTaskBo(taskHandle);
        List<ResourceInspectTaskSpare> taskSpareList = resourceInspectTaskSpareService.selectList(resourceInspectTaskSpare);
        resourceInspectTask.setTaskItemDetailList(itemParamList);
        resourceInspectTask.setSpareList(taskSpareList);
        return resourceInspectTask;
    }

    @Override
    public ResourceInspectTask startOrCancelTask(ResourceInspectTask resourceInspectTask) {
        String handle = resourceInspectTask.getHandle();
        String status = resourceInspectTask.getStatus();
        String reason = resourceInspectTask.getReason();

        String user = CommonMethods.getUser();
        ResourceInspectTask task = resourceInspectTaskService.getById(handle);
        task.setStatus(status);
        // 状态变更为“处理中/进行中”：插入数据执行人、实际开始时间
        if ( status.equals(Constants.INSPECTION_TASK_STATUS_DOING) ){
            task.setActualStartDate(LocalDateTime.now());
            task.setExecutor(user);
        }
        // 状态变更为“取消”：插入数据
        if( status.equals(Constants.INSPECTION_TASK_STATUS_CANCEL) ){
            task.setExecutor(CommonMethods.getUser());
            task.setReason(reason);
            task.setModifiedDateTime(LocalDateTime.now());
            // 取消时，创建新任务
            resourceInspectPlanService.autoCreateTaskByResourceInspectTask(task);
        }
        task.setModifyUser(user);
        task.setModifiedDateTime(LocalDateTime.now());
        // 保存数据
        resourceInspectTaskService.saveOrUpdate(task);
        // 获取检验项清单
        ResourceInspectTaskParam resourceInspectTaskParam = new ResourceInspectTaskParam();
        resourceInspectTaskParam.setResourceInspectTaskBo(handle);
        List<ResourceInspectTaskParam> taskParamList = resourceInspectTaskParamService.selectList(resourceInspectTaskParam);
        task.setTaskItemDetailList(taskParamList);
        // 获取备品清单
        ResourceInspectTaskSpare resourceInspectTaskSpare = new ResourceInspectTaskSpare();
        resourceInspectTaskSpare.setResourceInspectTaskBo(handle);
        List<ResourceInspectTaskSpare> taskSpareList = resourceInspectTaskSpareService.selectList(resourceInspectTaskSpare);
        task.setSpareList(taskSpareList);
        return task;
    }

    @Override
    public void saveOrUpdateTaskInfo(ResourceInspectTaskDto resourceInspectTaskDto) {
        // 站点、任务编号——任务handle、执行人、状态
        String site = CommonMethods.getSite();
        String taskNo = resourceInspectTaskDto.getTaskNo();
        String taskHandle = HandleEnum.RESOURCE_INSPECT_TASK.getHandle(site, taskNo);
        String executor = CommonMethods.getUser();
        String status = resourceInspectTaskDto.getStatus();
        // 检验项、备品清单
        List<ResourceInspectTaskParam> taskItemDetailList = resourceInspectTaskDto.getTaskItemDetailList();
        List<ResourceInspectTaskSpare> taskSpareList = resourceInspectTaskDto.getSpareList();
        // 任务主表字段：任务状态、修改人员、修改时间
        ResourceInspectTask task = resourceInspectTaskService.getById(taskHandle);
        task.setStatus(resourceInspectTaskDto.getStatus());
        task.setModifyUser(executor);
        task.setModifiedDateTime(LocalDateTime.now());
        // 若状态为完成，则获取检验结果
        if ( status.equals(Constants.INSPECTION_TASK_STATUS_COMPLETE) ){
            task.setResult("OK");
            for (ResourceInspectTaskParam taskParam:taskItemDetailList) {
                if (taskParam.getResult().equals("N")){
                    task.setResult("NG");
                    break;
                }
            }
            resourceInspectPlanService.autoCreateTaskByResourceInspectTask(task);
        }
        resourceInspectTaskService.saveOrUpdate(task);
        // 检验项全删、全增
        ResourceInspectTaskParam resourceInspectTaskParam = new ResourceInspectTaskParam();
        resourceInspectTaskParam.setResourceInspectTaskBo(taskHandle);
        resourceInspectTaskParamService.removeAll(resourceInspectTaskParam);

        for (ResourceInspectTaskParam taskParam:taskItemDetailList) {
            taskParam.setCreatedDateTime(LocalDateTime.now());
            taskParam.setCreateUser(executor);
        }
        resourceInspectTaskParamService.saveBatch(taskItemDetailList);
        // 备品全删、全增
        ResourceInspectTaskSpare resourceInspectTaskSpare = new ResourceInspectTaskSpare();
        resourceInspectTaskSpare.setResourceInspectTaskBo(taskHandle);
        resourceInspectTaskSpareService.removeAll(resourceInspectTaskSpare);
        for (ResourceInspectTaskSpare taskSpare:taskSpareList) {
            taskSpare.setResourceInspectTaskBo(taskHandle);
            taskSpare.setHandle(HandleEnum.RESOURCE_INSPECT_TASK_SPARE.getHandle(site,UUID.randomUUID().toString()));
            taskSpare.setCreatedDateTime(LocalDateTime.now());
            taskSpare.setCreateUser(executor);
        }
        resourceInspectTaskSpareService.saveBatch(taskSpareList);
    }

    @Override
    public ResourceInspectTask getInspectTaskByResource(ResourceInspectTaskDto resourceInspectTaskDto) {
        String site = CommonMethods.getSite();
        String currentUser = CommonMethods.getUser();
        String userBo = HandleEnum.USR.getHandle(site, currentUser);

        resourceInspectTaskDto.setSite(site);
        resourceInspectTaskDto.setCurrentUser(userBo);
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime compareStart = now.minusHours(now.getHour()).minusMinutes(now.getMinute());
        LocalDateTime compareEnd = compareStart.plusDays(1);
        resourceInspectTaskDto.setCompareStartDate(compareStart.toString().substring(0,16).replace('T',' '));
        resourceInspectTaskDto.setCompareEndDate(compareEnd.toString().substring(0,16).replace('T',' '));
        resourceInspectTaskDto.setCategory("DM");
        // 获取当日任务的handle
        List<ResourceInspectTaskDto> resourceInspectTaskList = resourceInspectTaskMapper.findResourceInspectTaskList(resourceInspectTaskDto);
        if (resourceInspectTaskList.size() > 0 ){
            ResourceInspectTask resourceInspectTask = new ResourceInspectTask();
            resourceInspectTask.setHandle(resourceInspectTaskList.get(0).getHandle());
            ResourceInspectTask resourceInspectTaskAll = resourceInspectTaskService.getResourceInspectTaskAll(resourceInspectTask);
            resourceInspectTaskAll.setResourceDescription(resourceInspectTaskList.get(0).getResourceDescription());
            return resourceInspectTaskAll;
        }
        throw BusinessException.build("未找到当日的点检任务！");
    }

    /***
     * 任务创建周期
     */
    private String getCycle(ResourceInspectTaskDto task){
        String frequencyUnit = task.getFrequencyUnit();
        String frequency = task.getFrequency();
        StringBuffer cycle = new StringBuffer("每");
        if (frequencyUnit == null){
            return "---";
        }
        switch (frequencyUnit){
            case "D":
                cycle = cycle.append(frequency).append("天");
                break;
            case "H":
                cycle = cycle.append(frequency).append("时");
                break;
            case "W":
                cycle = cycle.append(frequency).append("周");
                break;
            case "M":
                cycle = cycle.append(frequency).append("月");
                break;
        }
        return cycle.toString();
    }

    /***
     * 创建检验明细表
     */
    private void createAndSaveItemParams(String taskHandel,String inspectionItemBo){
        InspectionItemDetail inspectionItemDetail = new InspectionItemDetail();
        inspectionItemDetail.setInspectionItemBo(inspectionItemBo);
        List<InspectionItemDetail> itemDetails = inspectionItemDetailService.selectList(inspectionItemDetail);
        List<ResourceInspectTaskParam> paramList = new ArrayList<>();
        for (InspectionItemDetail detail:itemDetails) {
            ResourceInspectTaskParam resourceInspectTaskParam = new ResourceInspectTaskParam();
            // 检验项编号、描述；外键：任务handle、设备handle
            resourceInspectTaskParam.setHandle(taskHandel+";"+detail.getHandle());
            resourceInspectTaskParam.setInspectNo(detail.getParamNo());
            resourceInspectTaskParam.setDescription(detail.getDescription());
            resourceInspectTaskParam.setResourceInspectTaskBo(taskHandel);
            // 检验方法、数据类型、单位、
            resourceInspectTaskParam.setInspectMethod(detail.getInspectionMethod());
            resourceInspectTaskParam.setInspectDataType(detail.getParamType());
            resourceInspectTaskParam.setParamUnit(detail.getParamUnit());
            // 是否必填、最大最、最小值、标准值
            resourceInspectTaskParam.setRequired(detail.getIsRequired());
            BigDecimal maxValue = detail.getMaxValue();
            BigDecimal minValue = detail.getMinValue();
            if (maxValue != null){
                resourceInspectTaskParam.setMaxValue(maxValue.doubleValue());
            }
            if (minValue != null){
                resourceInspectTaskParam.setMinValue(minValue.doubleValue());
            }
            resourceInspectTaskParam.setStandardValue(detail.getStandardValue());
            resourceInspectTaskParam.setCreateUser(CommonMethods.getUser());
            resourceInspectTaskParam.setCreatedDateTime(LocalDateTime.now());
            paramList.add(resourceInspectTaskParam);
        }
        resourceInspectTaskParamService.saveBatch(paramList);
    }


}