package com.yunfeiyun.agmp.fms.service.impl;

import com.yunfeiyun.agmp.common.constant.ErrorCode;
import com.yunfeiyun.agmp.common.enums.TaskStatus;
import com.yunfeiyun.agmp.common.enums.TaskType;
import com.yunfeiyun.agmp.common.enums.TaskrcdAuditStatus;
import com.yunfeiyun.agmp.common.exception.BizException;
import com.yunfeiyun.agmp.common.utils.DateUtils;
import com.yunfeiyun.agmp.common.utils.SecurityUtils;
import com.yunfeiyun.agmp.common.utils.StringUtils;
import com.yunfeiyun.agmp.common.web.system.domain.SysRes;
import com.yunfeiyun.agmp.common.web.system.mapper.SysResMapper;
import com.yunfeiyun.agmp.fms.domain.*;
import com.yunfeiyun.agmp.fms.mapper.*;
import com.yunfeiyun.agmp.fms.domain.dto.FmsTaskrcdByTaskrcdIdDto;
import com.yunfeiyun.agmp.fms.domain.dto.FmsTaskrcdListDto;
import com.yunfeiyun.agmp.fms.domain.reqvo.FmsTaskrcdAuditReqVo;
import com.yunfeiyun.agmp.fms.domain.reqvo.FmsTaskrcdListReqVo;
import com.yunfeiyun.agmp.fms.domain.resvo.FmsTaskResVo;
import com.yunfeiyun.agmp.fms.domain.resvo.FmsTaskrcdByTaskrcdIdResVo;
import com.yunfeiyun.agmp.fms.domain.resvo.FmsTaskrcdInfoResVo;
import com.yunfeiyun.agmp.fms.domain.vo.FmsTaskassetVo;
import com.yunfeiyun.agmp.fms.domain.vo.FmsTaskmachineVo;
import com.yunfeiyun.agmp.fms.domain.vo.FmsTaskrcdVo;
import com.yunfeiyun.agmp.fms.service.IFmsTaskrcdService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import javax.annotation.Resource;
import java.util.*;

/**
 * 农事任务提交记录Service业务层处理
 * 
 * @author 杨晓辉
 * @date 2023-05-23
 */
@Service
public class FmsTaskrcdServiceImpl implements IFmsTaskrcdService 
{
    @Autowired
    private FmsTaskrcdMapper fmsTaskrcdMapper;
    @Autowired
    private FmsTaskMapper fmsTaskMapper;
    @Autowired
    private FmsTaskpickMapper fmsTaskpickMapper;
    @Autowired
    private FmsTaskpatrolMapper fmsTaskpatrolMapper;
    @Autowired
    private FmsTaskmachineMapper fmsTaskmachineMapper;
    @Autowired
    private FmsTaskassetMapper fmsTaskassetMapper;

    @Resource
    private SysResMapper sysResMapper;

    /**
     * 根据农事任务记录id查询农事记录信息
     *
     * @param taskrcdId 农事任务提交记录主键
     * @return 农事任务提交记录
     */
    public FmsTaskrcdByTaskrcdIdResVo selectFmsTaskrcdInfoByTaskrcdId(String taskrcdId){
        List<FmsTaskrcdByTaskrcdIdDto> fmsTaskrcdByTaskrcdIdDtos = fmsTaskrcdMapper.selectFmsTaskrcdInfoByTaskrcdId(taskrcdId);
        if (ObjectUtils.isEmpty(fmsTaskrcdByTaskrcdIdDtos)){
            throw new BizException(ErrorCode.FMS_TASK_RCD_NO_EXIST);
        }
        Map<String, FmsTaskmachineVo> fmsTaskmachineVoMap = new LinkedHashMap<>();
        Map<String, FmsTaskassetVo> fmsTaskassetVoMap = new LinkedHashMap<>();
        Set<String> resUrlSet = new LinkedHashSet<>();

        FmsTaskrcdByTaskrcdIdResVo fmsTaskrcdByTaskrcdIdResVo = new FmsTaskrcdByTaskrcdIdResVo();
        fmsTaskrcdByTaskrcdIdResVo.setTaskMachines(new ArrayList<>());
        fmsTaskrcdByTaskrcdIdResVo.setTaskAssets(new ArrayList<>());
        fmsTaskrcdByTaskrcdIdResVo.setTaskrcdPreviews(new ArrayList<>());

        BeanUtils.copyProperties(fmsTaskrcdByTaskrcdIdDtos.get(0), fmsTaskrcdByTaskrcdIdResVo);

        for (FmsTaskrcdByTaskrcdIdDto fmsTaskrcdByTaskrcdIdDto: fmsTaskrcdByTaskrcdIdDtos){
            String taskassetId = fmsTaskrcdByTaskrcdIdDto.getTaskassetId();
            String taskmachId = fmsTaskrcdByTaskrcdIdDto.getTaskmachId();

            if (taskassetId != null && !fmsTaskassetVoMap.containsKey(taskassetId)){
                FmsTaskassetVo fmsTaskassetVo = new FmsTaskassetVo();
                BeanUtils.copyProperties(fmsTaskrcdByTaskrcdIdDto, fmsTaskassetVo);
                fmsTaskassetVoMap.put(taskassetId, fmsTaskassetVo);
            }

            if (taskmachId != null && !fmsTaskmachineVoMap.containsKey(taskmachId)){
                FmsTaskmachineVo fmsTaskmachineVo = new FmsTaskmachineVo();
                BeanUtils.copyProperties(fmsTaskrcdByTaskrcdIdDto, fmsTaskmachineVo);
                fmsTaskmachineVoMap.put(taskmachId, fmsTaskmachineVo);
            }
            String resUrl = fmsTaskrcdByTaskrcdIdDto.getResUrl();
            if (!Objects.equals(resUrl, "") && resUrl != null){
                resUrlSet.add(resUrl);
            }
        }

        if (!fmsTaskmachineVoMap.isEmpty()){
            fmsTaskrcdByTaskrcdIdResVo.setTaskMachines(new ArrayList<>(fmsTaskmachineVoMap.values()));
        }
        if (!fmsTaskassetVoMap.isEmpty()){
            fmsTaskrcdByTaskrcdIdResVo.setTaskAssets(new ArrayList<>(fmsTaskassetVoMap.values()));
        }
        if (!resUrlSet.isEmpty()){
            fmsTaskrcdByTaskrcdIdResVo.setTaskrcdPreviews(new ArrayList<>(resUrlSet));
        }

        return fmsTaskrcdByTaskrcdIdResVo;
    }

    /**
     * 查询农事任务提交记录
     * 
     * @param taskrcdId 农事任务提交记录主键
     * @return 农事任务提交记录
     */
    @Override
    public FmsTaskrcd selectFmsTaskrcdByTaskrcdId(String taskrcdId)
    {
        return fmsTaskrcdMapper.selectFmsTaskrcdByTaskrcdId(taskrcdId);
    }

    private List<FmsTaskrcdVo> getFmsTaskrcdList(List<FmsTaskrcdListDto> taskrcdListDtos){
        Map<String, FmsTaskrcdVo> resultMap = new LinkedHashMap<>();

        Map<String, Map<String, FmsTaskmachineVo>> fmsTaskmachineVoMap = new LinkedHashMap<String, Map<String, FmsTaskmachineVo>>();
        Map<String, Map<String, FmsTaskassetVo>> fmsTaskassetVoMap = new LinkedHashMap<String, Map<String, FmsTaskassetVo>>();
        for (FmsTaskrcdListDto taskrcdListDto: taskrcdListDtos){
            String taskrcdId = taskrcdListDto.getTaskrcdId();
            if (!resultMap.containsKey(taskrcdId)){
                FmsTaskrcdVo fmsTaskrcdVo = new FmsTaskrcdVo();
                BeanUtils.copyProperties(taskrcdListDto, fmsTaskrcdVo);
                fmsTaskrcdVo.setTaskMachines(new ArrayList<>());
                fmsTaskrcdVo.setTaskAssets(new ArrayList<>());
                fmsTaskrcdVo.setTaskrcdPreviews(new ArrayList<>());
                resultMap.put(taskrcdId, fmsTaskrcdVo);

                fmsTaskmachineVoMap.put(taskrcdId, new LinkedHashMap<>());
                fmsTaskassetVoMap.put(taskrcdId, new LinkedHashMap<>());
            }

            FmsTaskrcdVo fmsTaskrcdVo = resultMap.get(taskrcdId);
            String resUrl = taskrcdListDto.getResUrl();
            if (!Objects.equals(resUrl, "") && resUrl != null){
                if (!fmsTaskrcdVo.getTaskrcdPreviews().contains(resUrl)){
                    fmsTaskrcdVo.getTaskrcdPreviews().add(resUrl);
                }
            }

            if(!StringUtils.isEmpty(taskrcdListDto.getTaskassetId())){
                FmsTaskassetVo fmsTaskassetVo = new FmsTaskassetVo();
                BeanUtils.copyProperties(taskrcdListDto, fmsTaskassetVo);
                if (!ObjectUtils.isEmpty(fmsTaskassetVo)){
                    fmsTaskassetVoMap.get(taskrcdId).put(fmsTaskassetVo.getTaskassetId(), fmsTaskassetVo);
                }
            }

            if (!StringUtils.isEmpty(taskrcdListDto.getTaskmachId())){
                FmsTaskmachineVo fmsTaskmachineVo = new FmsTaskmachineVo();
                BeanUtils.copyProperties(taskrcdListDto, fmsTaskmachineVo);
                if (!ObjectUtils.isEmpty(fmsTaskmachineVo)){
                    fmsTaskmachineVoMap.get(taskrcdId).put(fmsTaskmachineVo.getTaskmachId(), fmsTaskmachineVo);
                }
            }
        }
        ArrayList<FmsTaskrcdVo> resultList = new ArrayList<FmsTaskrcdVo>();
        for (Map.Entry<String, FmsTaskrcdVo> entry: resultMap.entrySet()){
            String key = entry.getKey();
            FmsTaskrcdVo resultTaskrcdVo = entry.getValue();
            if (fmsTaskmachineVoMap.containsKey(key)){
                resultTaskrcdVo.setTaskMachines(new ArrayList<>(fmsTaskmachineVoMap.get(key).values()));
            }
            if (fmsTaskassetVoMap.containsKey(key)){
                resultTaskrcdVo.setTaskAssets(new ArrayList<>(fmsTaskassetVoMap.get(key).values()));
            }
            resultList.add(resultTaskrcdVo);
        }
        return resultList;
    }

    /**
     * 根据任务ID查询农事任务提交记录
     *
     * @param taskId 农事任务主键
     * @return 农事任务提交记录
     */
    @Override
    public FmsTaskrcdInfoResVo selectFmsTaskrcdByTaskId(String taskId) {
        FmsTaskResVo fmsTaskResVo = this.fmsTaskMapper.getInfoByTaskId(taskId);
        if (ObjectUtils.isEmpty(fmsTaskResVo)){
            //  农事任务不存在
            throw new BizException(ErrorCode.FMS_TASK_TASK_NO_EXIST);
        }
        List<FmsTaskrcdListDto> taskrcdListDtos = this.fmsTaskrcdMapper.selectFmsTaskrcdByTaskId(taskId);
        List<FmsTaskrcdVo> fmsTaskrcdVos = this.getFmsTaskrcdList(taskrcdListDtos);
        FmsTaskrcdInfoResVo fmsTaskrcdInfoResVo = new FmsTaskrcdInfoResVo();
        BeanUtils.copyProperties(fmsTaskResVo, fmsTaskrcdInfoResVo);
        if (fmsTaskrcdVos.size() > 0){
            FmsTaskrcdVo fmsTaskrcdVo = fmsTaskrcdVos.get(0);
            fmsTaskrcdInfoResVo.setTaskrcdPreviews(fmsTaskrcdVo.getTaskrcdPreviews());
            fmsTaskrcdInfoResVo.setTaskAssets(fmsTaskrcdVo.getTaskAssets());
            fmsTaskrcdInfoResVo.setTaskMachines(fmsTaskrcdVo.getTaskMachines());
        }
        return fmsTaskrcdInfoResVo;
    }

    /**
     * 查询农事任务提交记录列表
     * 
     * @param fmsTaskrcdListReqVo 农事任务提交记录查询
     * @return 农事任务提交记录
     */
    @Override
    public List<FmsTaskrcdVo> selectFmsTaskrcdList(FmsTaskrcdListReqVo fmsTaskrcdListReqVo)
    {
        List<FmsTaskrcdListDto> taskrcdListDtos = fmsTaskrcdMapper.selectFmsTaskrcdList(fmsTaskrcdListReqVo);
        return this.getFmsTaskrcdList(taskrcdListDtos);
    }

    /**
     * 新增农事任务提交记录
     * 
     * @param fmsTaskrcdVo 农事任务提交记录
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertFmsTaskrcd(FmsTaskrcdVo fmsTaskrcdVo)
    {
        String taskId = fmsTaskrcdVo.getTaskId();
        FmsTask fmsTask = this.fmsTaskMapper.selectFmsTaskByTaskId(taskId);
        if (ObjectUtils.isEmpty(fmsTask)){
            //  农事任务不存在
            throw new BizException(ErrorCode.FMS_TASK_TASK_NO_EXIST);
        }
        String taskType = fmsTask.getTaskType();
        String taskStatus = fmsTask.getTaskStatus();
        // 只允许在任务状态为进行中的任务进行提交
        if (!TaskStatus.EXECUTING.equal(taskStatus)){
            throw new BizException(ErrorCode.FMS_TASK_RCD_TASK_STATUS_EXIST);
        }

        FmsTaskrcd fmsTaskrcd = new FmsTaskrcd();
        BeanUtils.copyProperties(fmsTaskrcdVo, fmsTaskrcd);
        String taskrcdId = fmsTaskrcd.getId();
        fmsTaskrcd.setTaskrcdId(taskrcdId);
        fmsTaskrcd.setTaskrcdAuditstatus(TaskrcdAuditStatus.UNAUDITED.getCode());
        fmsTaskrcd.setTaskrcdSubmitdate(DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:ss").toString());
        this.fmsTaskrcdMapper.insertFmsTaskrcd(fmsTaskrcd);

        if (!TaskType.PATROL.equal(taskType)){
            ArrayList<FmsTaskmachineVo> machVos = fmsTaskrcdVo.getTaskMachines();
            if (machVos != null){
                ArrayList<FmsTaskmachine> fmsTaskmachines = new ArrayList<>();
                for (FmsTaskmachineVo machineVo: machVos){
                    FmsTaskmachine fmsTaskMachine = new FmsTaskmachine();
                    BeanUtils.copyProperties(machineVo, fmsTaskMachine);
                    fmsTaskMachine.setTaskmachId(fmsTaskMachine.getId());
                    fmsTaskMachine.setTaskrcdId(taskrcdId);

                    fmsTaskmachines.add(fmsTaskMachine);
                }
                // 创建农具使用记录
                if( !fmsTaskmachines.isEmpty()){
                    this.fmsTaskmachineMapper.insertFmsTaskmachineBatch(fmsTaskmachines);
                }
            }

            ArrayList<FmsTaskassetVo> taskAssetVos = fmsTaskrcdVo.getTaskAssets();
            if (taskAssetVos != null){
                ArrayList<FmsTaskasset> fmsTaskassets = new ArrayList<>();
                for (FmsTaskassetVo assetVo: taskAssetVos){
                    FmsTaskasset taskAsset = new FmsTaskasset();
                    BeanUtils.copyProperties(assetVo, taskAsset);
                    taskAsset.setTaskassetId(taskAsset.getId());
                    taskAsset.setTaskrcdId(taskrcdId);

                    fmsTaskassets.add(taskAsset);
                }

                // 创建农资使用记录
                if (!fmsTaskassets.isEmpty()){
                    this.fmsTaskassetMapper.insertFmsTaskassetBatch(fmsTaskassets);
                }
            }
        }
        // 绑定资源对象
        ArrayList<String> previews = fmsTaskrcdVo.getTaskrcdPreviews();
        if(StringUtils.isNotEmpty(previews)){
            List<SysRes> sysResList = this.sysResMapper.selectSysResListByResId(previews);
            List<SysRes> tempSysResList = new ArrayList<>();
            for(SysRes sysRes: sysResList){
                SysRes tempSysRes = new SysRes();
                tempSysRes.setResId(sysRes.getResId());
                tempSysRes.setResBusId(taskrcdId);
                tempSysResList.add(tempSysRes);
            }
            if (!tempSysResList.isEmpty()){
                this.sysResMapper.updateSysResByResIds(tempSysResList);
            }

        }

        FmsTask newFmsTask = new FmsTask();
        newFmsTask.setTaskId(fmsTask.getTaskId());
        newFmsTask.setTaskStatus(TaskStatus.UNAUDITED.getCode());
        return this.fmsTaskMapper.updateFmsTask(newFmsTask);
    }

    /**
     * 修改农事任务提交记录
     * 
     * @param fmsTaskrcd 农事任务提交记录
     * @return 结果
     */
    @Override
    public int updateFmsTaskrcd(FmsTaskrcd fmsTaskrcd)
    {
        return fmsTaskrcdMapper.updateFmsTaskrcd(fmsTaskrcd);
    }

    /**
     * 批量删除农事任务提交记录
     * 
     * @param taskrcdIds 需要删除的农事任务提交记录主键
     * @return 结果
     */
    @Override
    public int deleteFmsTaskrcdByTaskrcdIds(String[] taskrcdIds)
    {
        return fmsTaskrcdMapper.deleteFmsTaskrcdByTaskrcdIds(taskrcdIds);
    }

    /**
     * 删除农事任务提交记录信息
     * 
     * @param taskrcdId 农事任务提交记录主键
     * @return 结果
     */
    @Override
    public int deleteFmsTaskrcdByTaskrcdId(String taskrcdId)
    {
        return fmsTaskrcdMapper.deleteFmsTaskrcdByTaskrcdId(taskrcdId);
    }

    /**
     * 审核农事任务提交记录
     * @param fmsTaskrcdAuditReqVo 农事任务审核信息
     * @return 结果信息
     * */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int audit(FmsTaskrcdAuditReqVo fmsTaskrcdAuditReqVo) {
        FmsTaskrcd fmsTaskrcd = fmsTaskrcdMapper.selectFmsTaskrcdByTaskrcdId(fmsTaskrcdAuditReqVo.getTaskrcdId());
        if(ObjectUtils.isEmpty(fmsTaskrcd)){
            // 农事任务提交记录不存在
            throw new BizException(ErrorCode.FMS_TASK_RCD_NO_EXIST);
        }
        if(!TaskrcdAuditStatus.UNAUDITED.equal(fmsTaskrcd.getTaskrcdAuditstatus())) {
            // 农事任务提交记录重复审核
            throw new BizException(ErrorCode.FMS_TASK_RCD_REPEATED_AUDIT);
        }
        FmsTask fmsTask = fmsTaskMapper.selectFmsTaskByTaskId(fmsTaskrcd.getTaskId());
        if(ObjectUtils.isEmpty(fmsTask)){
            // 农事任务不存在
            throw new BizException(ErrorCode.FMS_TASK_TASK_NO_EXIST);
        }
        if(!TaskStatus.UNAUDITED.equal(fmsTask.getTaskStatus())) {
            // 农事任务提交记录重复审核
            throw new BizException(ErrorCode.FMS_TASK_TASK_REPEATED_AUDIT);
        }
        // 更新农事任务提交记录审核状态
        fmsTaskrcd.setTaskrcdAuditcontent(fmsTaskrcdAuditReqVo.getComments());
        fmsTaskrcd.setTaskrcdAuditdate(DateUtils.getTime());
        fmsTaskrcd.setTaskrcdAuditstatus(fmsTaskrcdAuditReqVo.getTaskrcdAuditstatus());
        fmsTaskrcd.setTaskrcdAuditor(SecurityUtils.getLoginUser().getUserId());
        fmsTaskrcdMapper.updateFmsTaskrcd(fmsTaskrcd);
        if(TaskrcdAuditStatus.PASS.equal(fmsTaskrcdAuditReqVo.getTaskrcdAuditstatus())){
            // 农事任务提交记录审核通过
            fmsTask.setTaskStatus(TaskStatus.COMPLETED.getCode());
            fmsTask.setTaskCompletedate(DateUtils.getTime());
        }else {
            // 农事任务提交记录审核不通过
            fmsTask.setTaskStatus(TaskStatus.EXECUTING.getCode());
        }
        if(TaskType.PICK.equal(fmsTask.getTaskType())){
            //采收任务
            pickTaskAudit(fmsTaskrcd);
        }
        if(TaskType.PATROL.equal(fmsTask.getTaskType())){
            // 巡田任务
            patrolTaskAudit(fmsTaskrcd);
        }
        fmsTaskMapper.updateFmsTask(fmsTask);
        return fmsTaskMapper.updateFmsTask(fmsTask);
    }

    private void pickTaskAudit(FmsTaskrcd fmsTaskrcd) {
        FmsTaskpick fmsTaskpick = fmsTaskpickMapper.selectFmsTaskpickByTaskId(fmsTaskrcd.getTaskId());
        if (ObjectUtils.isEmpty(fmsTaskpick)){
            // 采收任务不存在
            throw new BizException(ErrorCode.FMS_TASK_PICK_TASK_NO_EXIST);
        }
        fmsTaskpick.setPickWeight(fmsTaskrcd.getTaskrcdWeight());
        fmsTaskpick.setPickDate(fmsTaskrcd.getTaskrcdCompletedate());
        // 更新采收任务
        fmsTaskpickMapper.updateFmsTaskpick(fmsTaskpick);
    }

    private void patrolTaskAudit(FmsTaskrcd fmsTaskrcd) {
        FmsTaskpatrol fmsTaskpatrol = fmsTaskpatrolMapper.selectFmsTaskpatrolByTaskId(fmsTaskrcd.getTaskId());
        if (ObjectUtils.isEmpty(fmsTaskpatrol)){
            // 巡田任务不存在
            throw new BizException(ErrorCode.FMS_TASK_PATROL_TASK_NO_EXIST);
        }
        fmsTaskpatrol.setTaskpatrolWay(fmsTaskrcd.getTaskrcdPatrolway());
        fmsTaskpatrol.setTaskpatrolHour(fmsTaskrcd.getTaskrcdHour());
        // 更新巡田任务
        fmsTaskpatrolMapper.updateFmsTaskpatrol(fmsTaskpatrol);
    }


}
