package com.bonus.material.purchase.service.impl;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.bonus.common.biz.constant.MaterialConstants;
import com.bonus.common.biz.enums.HttpCodeEnum;
import com.bonus.common.biz.enums.MaTypeManageTypeEnum;
import com.bonus.common.biz.enums.PurchaseTaskStatusEnum;
import com.bonus.common.core.utils.StringUtils;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.material.ma.mapper.MachineMapper;
import com.bonus.material.purchase.config.RemoteConfig;
import com.bonus.material.purchase.domain.PurchaseCheckDetails;
import com.bonus.material.purchase.domain.dto.PurchaseDto;
import com.bonus.material.purchase.mapper.PurchaseBindMapper;
import com.bonus.material.purchase.mapper.PurchaseStorageMapper;
import com.bonus.material.purchase.service.IPurchaseStorageService;
import com.bonus.material.purchase.domain.vo.PurchaseVo;
import com.bonus.material.task.mapper.TmTaskMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 新购入库实现层
 * @Author ma_sh
 * @create 2024/10/21 13:53
 */
@Service
public class PurchaseStorageServiceImpl implements IPurchaseStorageService {

    @Resource
    private PurchaseStorageMapper purchaseStorageMapper;

    @Resource
    private MachineMapper machineMapper;

    @Resource
    private PurchaseBindMapper purchaseBindMapper;

    @Resource
    private TmTaskMapper tmTaskMapper;

    @Resource
    private RemoteConfig remoteConfig;

    /**
     * 查询所有
     * @param dto
     * @return
     */
    @Override
    public List<PurchaseVo> selectAll(PurchaseDto dto) {
        List<PurchaseVo> list = purchaseStorageMapper.selectAll(dto);
        if (CollectionUtils.isNotEmpty(list)) {
            for (PurchaseVo purchaseVo : list) {
                purchaseVo.setStatusName(String.valueOf(PurchaseTaskStatusEnum.getByStatus(purchaseVo.getStatus())));
            }
        }
        return list;
    }

    /**
     * 查询二级明细详情
     * @param dto
     * @return
     */
    @Override
    public List<PurchaseVo> getDetails(PurchaseDto dto) {
        List<PurchaseVo> list = purchaseBindMapper.getDetails(dto);
        Map<String, String> labelMap = remoteConfig.getDictValue("purchase_task_status");
        if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(list)) {
            for (PurchaseVo purchaseVo : list) {
                // 更新状态名称
                Integer status = purchaseVo.getStatus();
                if (status != null) {
                    String dictValue = labelMap.get(status.toString());
                    purchaseVo.setStatusName(dictValue);
                }
            }
        }
        return list;
    }

    /**
     * 入库或批量入库
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult warehouse(PurchaseDto dto) {
        //内层入库
        return processByPurchaseIds(dto);
        /*if (dto.getTaskId() != null) {
            //外层入库
            return processByTaskIds(dto);
        }*/
    }

    /**
     * 驳回或批量驳回
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult reject(PurchaseDto dto) {
        if (dto.getTaskId() != null) {
            //外层驳回
            return rejectByTaskIds(dto);
        } else if (dto.getPurchaseId() != null) {
            //内层驳回
            return rejectByPurchaseIds(dto);
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 查询机具详情
     * @param dto
     * @return
     */
    @Override
    public AjaxResult getMachineById(PurchaseDto dto) {
        List<PurchaseCheckDetails> list = purchaseBindMapper.getMachineById(dto);
        return AjaxResult.success(list);
    }

    /**
     * 内层驳回
     * @param purchaseDto
     * @return
     */
    private AjaxResult rejectByPurchaseIds(PurchaseDto purchaseDto) {
        List<Integer> purchaseIdList = parseIds(purchaseDto.getPurchaseId());
        purchaseDto.setStatus(PurchaseTaskStatusEnum.TO_STORE_AFTER_REJECT.getStatus());
        int result = 0;
        try {
            for (Integer purchaseId : purchaseIdList) {
                purchaseDto.setPurchaseId(String.valueOf(purchaseId));
                List<PurchaseVo> details = purchaseBindMapper.getDetails(purchaseDto);
                if (CollectionUtils.isNotEmpty(details)) {
                    result += updateRejectAndStatus(purchaseId);
                    List<PurchaseVo> statusList = purchaseStorageMapper.select(details.get(0).getTaskId().toString());
                    result += updateTaskStatus(statusList);
                }
                if (result > 0) {
                    return AjaxResult.success("驳回成功");
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 更新驳回状态和状态
     * @param purchaseId
     * @return
     */
    private int updateRejectAndStatus(int purchaseId) {
        return purchaseStorageMapper.updateStatusById(PurchaseTaskStatusEnum.TO_STORE_AFTER_REJECT.getStatus(), purchaseId);
    }

    /**
     * 外层驳回
     * @param dto
     * @return
     */
    private AjaxResult rejectByTaskIds(PurchaseDto dto) {
        List<Integer> taskIdList = parseIds(dto.getTaskId());
        int result = 0;
        try {
            for (Integer taskId : taskIdList) {
                dto.setTaskId(String.valueOf(taskId));
                List<PurchaseVo> details;
                details = purchaseBindMapper.getDetails(dto);
                for (PurchaseVo purchaseVo : details) {
                    if (purchaseVo.getStatus().equals(PurchaseTaskStatusEnum.TO_STORE_AFTER_REJECT.getStatus()) || purchaseVo.getStatus().equals(PurchaseTaskStatusEnum.TO_STORE.getStatus())) {
                        result += purchaseStorageMapper.updateStatusById(PurchaseTaskStatusEnum.TO_STORE_AFTER_REJECT.getStatus(), Integer.parseInt(purchaseVo.getPurchaseId()));
                    }
                }
                details = purchaseBindMapper.getDetails(dto);
                result += updateTaskStatus(details);
            }
            if (result > 0) {
                return AjaxResult.success("驳回成功");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 内层入库
     * @param purchaseDto
     * @return
     */
    private AjaxResult processByPurchaseIds(PurchaseDto purchaseDto) {
        int result = 0;
        try {
            //判断为数量还是编码入库
            if (CollectionUtils.isEmpty(purchaseDto.getInPutList())) {
              //数量入库
                List<PurchaseVo> details = purchaseBindMapper.getDetails(purchaseDto);
                result += updatePurchaseInfoAndDetails(details.get(0), Integer.parseInt(purchaseDto.getPurchaseId()));
            } else {
                //编码入库
                List<PurchaseVo> purchaseVoList = purchaseBindMapper.selectPurchaseCheckInfoById(purchaseDto);
                result += purchaseStorageMapper.updateNum(purchaseDto.getPurchaseId(), purchaseDto.getInPutList().size());
                for (PurchaseDto dto : purchaseDto.getInPutList()) {
                    if (CollectionUtils.isNotEmpty(purchaseVoList)) {
                        for (PurchaseVo purchaseVo : purchaseVoList) {
                            if (purchaseVo.getMaCode().equals(dto.getMaCode())) {
                                dto.setOutFacCode(purchaseVo.getOutFacCode() == null ? "" : purchaseVo.getOutFacCode());
                                dto.setProductDate(purchaseVo.getProductDate() == null ? null : purchaseVo.getProductDate());
                            }
                        }
                    }
                    dto.setTypeId(purchaseDto.getTypeId());
                    result += purchaseStorageMapper.insertMachine(dto);
                    List<PurchaseCheckDetails> list = purchaseBindMapper.getMachineById(purchaseDto);
                    if (CollectionUtils.isNotEmpty(list)) {
                        result += purchaseStorageMapper.updateStatusById(PurchaseTaskStatusEnum.TO_STORE.getStatus(), Integer.parseInt(purchaseDto.getPurchaseId()));
                    } else {
                        result += purchaseStorageMapper.updateStatusById(PurchaseTaskStatusEnum.IN_STORE.getStatus(), Integer.parseInt(purchaseDto.getPurchaseId()));
                    }
                }
            }
            List<PurchaseVo> statusList = purchaseStorageMapper.select(purchaseDto.getTaskId());
            result += updateTaskStatus(statusList);
            if (result > 0) {
                return AjaxResult.success("入库成功");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 更新采购单和采购明细
     * @param detail
     * @param purchaseId
     * @return
     */
    private int updatePurchaseInfoAndDetails(PurchaseVo detail, int purchaseId) {
        int result = purchaseStorageMapper.updateNum(detail.getPurchaseId(), detail.getCheckNum());
        result += purchaseStorageMapper.updateStorageNum(detail.getCheckNum(), detail.getTypeId());
        return result + purchaseStorageMapper.updateStatusById(PurchaseTaskStatusEnum.IN_STORE.getStatus(), purchaseId);
    }

    /**
     * 外层入库
     * @param dto
     * @return
     */
    private AjaxResult processByTaskIds(PurchaseDto dto) {
        List<Integer> taskIdList = parseIds(dto.getTaskId());
        int result = 0;
        try {
            for (Integer taskId : taskIdList) {
                dto.setTaskId(String.valueOf(taskId));
                List<PurchaseVo> details;
                details = purchaseBindMapper.getDetails(dto);
                result += updateDetailsAndStatus(details);
                details = purchaseBindMapper.getDetails(dto);
                result += updateTaskStatus(details);
            }
            if (result > 0) {
                return AjaxResult.success("入库成功");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 更新采购单和采购明细状态
     * @param details
     * @return
     */
    private int updateDetailsAndStatus(List<PurchaseVo> details) {
        return details.stream()
                .mapToInt(detail -> {
                    int result = purchaseStorageMapper.updateNum(detail.getPurchaseId(), detail.getBindNum());
                    result += purchaseStorageMapper.updateStatusById(PurchaseTaskStatusEnum.IN_STORE.getStatus(), Integer.parseInt(detail.getPurchaseId()));
                    if (MaTypeManageTypeEnum.CODE_DEVICE.getTypeId().equals(Integer.valueOf(detail.getManageType()))) {
                        //根据类型id获取设备详情信息
                        //result += purchaseStorageMapper.insertMachine(detail);
                    } else if (MaTypeManageTypeEnum.NUMBER_DEVICE.getTypeId().equals(Integer.valueOf(detail.getManageType()))) {
                        result += purchaseStorageMapper.updateStorageNum(detail.getBindNum(), detail.getTypeId());
                    }
                    return result;
                }).sum();
    }

    /**
     * 更新任务状态
     * @param details
     * @return
     */
    private int updateTaskStatus(List<PurchaseVo> details) {
        Map<Integer, List<Integer>> groupedByIdStatus = details.stream()
                .collect(Collectors.groupingBy(
                        PurchaseVo::getTaskId,
                        Collectors.mapping(PurchaseVo::getStatus, Collectors.toList())
                ));

        return groupedByIdStatus.entrySet().stream()
                .mapToInt(entry -> {
                    Integer id = entry.getKey();
                    List<Integer> statusList = entry.getValue();
//                    if (statusList.contains(PurchaseTaskStatusEnum.TO_STORE.getStatus()) || statusList.contains(PurchaseTaskStatusEnum.TO_STORE_AFTER_REJECT.getStatus())) {
//                        return tmTaskMapper.updateStatusById(PurchaseTaskStatusEnum.TASK_IN_PROGRESS.getStatus(), id.toString());
//                    } else
                    if (!statusList.contains(PurchaseTaskStatusEnum.TO_STORE.getStatus()) && !statusList.contains(PurchaseTaskStatusEnum.TO_STORE_AFTER_REJECT.getStatus())
                                            && statusList.stream().allMatch(status -> status.equals(PurchaseTaskStatusEnum.IN_STORE.getStatus()))) {
                        return tmTaskMapper.updateTaskStatus(id.toString(), PurchaseTaskStatusEnum.TASK_FINISHED.getStatus());
                    }
                    return 0;
                }).sum();
    }

    /**
     * 将字符串转换为Integer集合
     * @param ids
     * @return
     */
    private List<Integer> parseIds(String ids) {
        return Arrays.stream(ids.split(","))
                .map(Integer::parseInt)
                .collect(Collectors.toList());
    }
}
