package com.casic.missiles.service.Impl.equipment;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.missiles.core.base.service.IBaseExportService;
import com.casic.missiles.dto.IdDTO;
import com.casic.missiles.dto.ReturnDTO;
import com.casic.missiles.dto.ReturnUtil;
import com.casic.missiles.dto.equipment.EquipmentApplyRequest;
import com.casic.missiles.dto.equipment.StateManageRequest;
import com.casic.missiles.dto.equipment.StateManageResponse;
import com.casic.missiles.dto.flowable.AllApproveDTO;
import com.casic.missiles.dto.flowable.ToBeApprovedDTO;
import com.casic.missiles.enums.system.ApprovalStatusEnum;
import com.casic.missiles.enums.BusinessExceptionEnum;
import com.casic.missiles.enums.ExportEnum;
import com.casic.missiles.exception.BusinessException;
import com.casic.missiles.mapper.equipment.EquipmentApplyEquipmentMapper;
import com.casic.missiles.mapper.equipment.EquipmentApplyFileMapper;
import com.casic.missiles.mapper.equipment.EquipmentApplyMapper;
import com.casic.missiles.mapper.equipment.EquipmentStateManageMapper;
import com.casic.missiles.model.equipment.EquipmentApply;
import com.casic.missiles.model.equipment.EquipmentApplyEquipment;
import com.casic.missiles.model.equipment.EquipmentApplyFile;
import com.casic.missiles.model.equipment.EquipmentStandardEquipmentFile;
import com.casic.missiles.service.IBaseApprovalService;
import com.casic.missiles.service.equipment.IEquipmentApplyFileService;
import com.casic.missiles.service.equipment.IEquipmentStateManageService;
import com.casic.missiles.utils.DictCodeUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

@Service("IEquipmentStateManageService")
public class EquipmentStateManageServiceImpl implements IEquipmentStateManageService {

    @Resource
    private EquipmentApplyMapper equipmentApplyMapper;

    @Resource
    private EquipmentStateManageMapper stateManageMapper;

    @Resource
    private EquipmentApplyFileMapper equipmentApplyFileMapper;

    @Resource
    private IEquipmentApplyFileService applyFileService;

    @Resource
    private IBaseExportService iBaseExportService;

    @Resource
    private IBaseApprovalService baseApprovalService;

    @Resource
    private EquipmentApplyEquipmentMapper equipmentMapper;

    @Override
    public Page<StateManageResponse> stateManageList(Page<StateManageResponse> page, StateManageRequest request) throws Exception {
        Page<StateManageResponse> resultPage;
        List<String> businessKeys = new ArrayList<>();
        boolean searchBusinessKey = true;
        String status = request.getApprovalStatus();
        Map<String,String> taskMap = new HashMap<>(); // businessKey-taskId, 待审批列表用
        List<String> rejectBusinessKey = new ArrayList<>();// 未通过-驳回
        Map<String,Integer> decisionItemMap = new HashMap<>(); // 可选决策项map
        switch (request.getApprovalStatus()){
            case ApprovalStatusEnum.TO_BE_APPROVED:
                List<ToBeApprovedDTO> toBeApprovedList = baseApprovalService.getToBeApprovedList(request.getFormId());
                if(ObjectUtil.isNotEmpty(toBeApprovedList)){
                    businessKeys = toBeApprovedList.stream().map(ToBeApprovedDTO::getBusinessKey).distinct().collect(Collectors.toList());
                }
                toBeApprovedList.forEach(toBeApprovedDTO -> {taskMap.put(toBeApprovedDTO.getBusinessKey(),toBeApprovedDTO.getTaskId());});
                toBeApprovedList.forEach(toBeApprovedDTO -> {decisionItemMap.put(toBeApprovedDTO.getBusinessKey(),toBeApprovedDTO.getDecisionItem());});
                break;
            case ApprovalStatusEnum.IN_APPROVED:
                businessKeys = baseApprovalService.getInApprovedList(request.getFormId());
                break;
            case ApprovalStatusEnum.PASSED:
                businessKeys = baseApprovalService.getPassedList(request.getFormId());
                break;
            case ApprovalStatusEnum.FAILED:
                businessKeys = baseApprovalService.getFailedList(request.getFormId());
                rejectBusinessKey = baseApprovalService.getFailedRejectList(request.getFormId()); //未通过-驳回
                businessKeys.addAll(rejectBusinessKey);
                break;
            case ApprovalStatusEnum.CANCELED:
                businessKeys = baseApprovalService.getCanceledList(request.getFormId());
                break;
            case ApprovalStatusEnum.ALL:
                List<AllApproveDTO> allList = baseApprovalService.getAllList(request.getFormId());
                businessKeys = allList.stream().map(AllApproveDTO::getBusinessKey).distinct().collect(Collectors.toList());
                allList.forEach(allApprovedDTO -> {taskMap.put(allApprovedDTO.getBusinessKey(),allApprovedDTO.getStatus());});
                break;
            default:
                // 草稿箱，直接查表，不用查工作流
                searchBusinessKey = false;
                break;
        }
        if(searchBusinessKey){
            request.setApprovalStatus(null);
            if(!CollectionUtils.isEmpty(businessKeys)){
                request.setBusinessKeys(businessKeys);
            }else{
                return page;
            }
        }
        resultPage = stateManageMapper.stateManageList(page,request);
        for (StateManageResponse item: resultPage.getRecords()) {
            if(searchBusinessKey){
                item.setApprovalStatus(status);
                // 未通过-驳回状态
                if(status.equals(ApprovalStatusEnum.FAILED) && rejectBusinessKey.contains(item.getId().toString())){
                    item.setApprovalStatus(ApprovalStatusEnum.FAILED_REJECT);
                }
            }
            if(ApprovalStatusEnum.TO_BE_APPROVED.equals(status)){
                item.setTaskId(taskMap.get(item.getId().toString()));
                item.setDecisionItem(decisionItemMap.get(item.getId().toString()));
            }
            if(ApprovalStatusEnum.ALL.equals(status)){
                item.setApprovalStatus(taskMap.get(String.valueOf(item.getId())));
            }
            DictCodeUtils.convertDictCodeToName(item);
        }
        return resultPage;
    }

    @Override
    public StateManageResponse selectStateManageInfo(IdDTO idDto) throws Exception {
        StateManageResponse stateManageResponse = stateManageMapper.selectById(idDto.getId());
        DictCodeUtils.convertDictCodeToName(stateManageResponse);
        QueryWrapper<EquipmentApplyFile> wrapper = new QueryWrapper<>();
        wrapper.eq("apply_id",idDto.getId());
        List<EquipmentApplyFile> equipmentApplyFiles = equipmentApplyFileMapper.selectList(wrapper);
        stateManageResponse.setFileList(equipmentApplyFiles);
        return stateManageResponse;
    }

    @Override
    public void exportStateManageList(StateManageRequest request, HttpServletResponse response) throws Exception {
        List<StateManageResponse> resultList;
        if(!CollectionUtils.isEmpty(request.getIds())){
            StateManageRequest applyRequest = new StateManageRequest();
            applyRequest.setIds(request.getIds());
            resultList = stateManageMapper.stateManageList(applyRequest);
        }else{
            request.setBusinessKeys(getBusinessKeys(request.getApprovalStatus(), request.getFormId(),baseApprovalService));
            if(!request.getApprovalStatus().equals(ApprovalStatusEnum.DRAFT)){
                request.setApprovalStatus(null);
            }
            resultList = stateManageMapper.stateManageList(request);
        }
        for (StateManageResponse item: resultList) {
            DictCodeUtils.convertDictCodeToName(item);
        }
        iBaseExportService.exportExcel(response, StateManageResponse.class,resultList, ExportEnum.STATE_MANAGE_APPLY.getSheetName());
    }

    @Override
    public ReturnDTO updateEquipmentApply(StateManageResponse response) {
        EquipmentApply equipmentApply = new EquipmentApply();
        BeanUtils.copyProperties(response, equipmentApply);
        if(equipmentApplyMapper.updateById(equipmentApply)>0){
            EquipmentApplyEquipment equipment = new EquipmentApplyEquipment(response.getApplyEquipmentId(),response.getEquipmentId(),response.getFinancialValue(),response.getAssetOriginValue());
            // 删除老的文件，更新新的文件
            if (!CollectionUtils.isEmpty(response.getFileList())) {
                QueryWrapper<EquipmentApplyFile> wrapper = new QueryWrapper<>();
                wrapper.eq("apply_id", response.getId());
                equipmentApplyFileMapper.delete(wrapper);
                for (EquipmentApplyFile file : response.getFileList()) {
                    file.setApplyId(response.getId());
                }
                if(!applyFileService.saveBatch(response.getFileList())){
                    throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED);
                }
            }
            if(equipmentMapper.updateById(equipment)>0)return ReturnUtil.success();
            throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED);
        }
        throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED);
    }

    @Override
    @Transactional
    public ReturnDTO failUpdate(StateManageResponse response) {
        EquipmentApply equipmentApply = new EquipmentApply();
        BeanUtils.copyProperties(response, equipmentApply);
        // 修改申请基本信息
        if(equipmentApplyMapper.updateById(equipmentApply)>0){
            EquipmentApplyEquipment equipment = new EquipmentApplyEquipment(response.getApplyEquipmentId(),response.getEquipmentId(),response.getFinancialValue(),response.getAssetOriginValue());
            if(equipmentMapper.updateById(equipment)>0){
                baseApprovalService.failUpdate(equipmentApply.getProcessId());
                return ReturnUtil.success();
            }
            throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED);
        }
        throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED);
    }

    public static List<String> getBusinessKeys(String approvalStatus,String formId,IBaseApprovalService baseApprovalService) {
        List<String> businessKeys;
        List<String> rejectBusinessKey;
        switch (approvalStatus){
            case ApprovalStatusEnum.TO_BE_APPROVED:
                List<ToBeApprovedDTO> toBeApprovedList = baseApprovalService.getToBeApprovedList(formId);
                businessKeys = toBeApprovedList.stream().map(ToBeApprovedDTO::getBusinessKey).distinct().collect(Collectors.toList());
                break;
            case ApprovalStatusEnum.IN_APPROVED:
                businessKeys = baseApprovalService.getInApprovedList(formId);
                break;
            case ApprovalStatusEnum.PASSED:
                businessKeys = baseApprovalService.getPassedList(formId);
                break;
            case ApprovalStatusEnum.FAILED:
                businessKeys = baseApprovalService.getFailedList(formId);
                rejectBusinessKey = baseApprovalService.getFailedRejectList(formId); //未通过-驳回
                businessKeys.addAll(rejectBusinessKey);
                break;
            case ApprovalStatusEnum.CANCELED:
                businessKeys = baseApprovalService.getCanceledList(formId);
                break;
            case ApprovalStatusEnum.ALL:
                List<AllApproveDTO> allList = baseApprovalService.getAllList(formId);
                businessKeys = allList.stream().map(AllApproveDTO::getBusinessKey).distinct().collect(Collectors.toList());
                break;
            default:
                businessKeys = new ArrayList<>();
                break;
        }
        return businessKeys;
    }
}
