package net.lab1024.sa.admin.module.business.wms.shipping.pickDetail.service.impl;

import jakarta.annotation.Resource;
import net.lab1024.sa.admin.module.business.wms.base.item.domain.entity.ItemEntity;
import net.lab1024.sa.admin.module.business.wms.base.item.manager.ItemManager;
import net.lab1024.sa.admin.module.business.wms.base.item.service.ItemQueryService;
import net.lab1024.sa.admin.module.business.wms.shipping.pick.constant.PickOrderStatusEnum;
import net.lab1024.sa.admin.module.business.wms.shipping.pick.domain.entity.PickEntity;
import net.lab1024.sa.admin.module.business.wms.shipping.pick.manager.PickManager;
import net.lab1024.sa.admin.module.business.wms.shipping.pickDetail.domain.entity.PickDetailEntity;
import net.lab1024.sa.admin.module.business.wms.shipping.pickDetail.domain.form.PickDetailAddForm;
import net.lab1024.sa.admin.module.business.wms.shipping.pickDetail.domain.form.PickDetailUpdateForm;
import net.lab1024.sa.admin.module.business.wms.shipping.pickDetail.manager.PickDetailManager;
import net.lab1024.sa.admin.module.business.wms.shipping.pickDetail.service.PickDetailQueryService;
import net.lab1024.sa.admin.module.business.wms.shipping.pickDetail.service.PickDetailService;
import net.lab1024.sa.admin.util.JoinerResult;
import net.lab1024.sa.admin.util.ResponseDTOUtil;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.util.SmartBigDecimalUtil;
import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum;
import net.lab1024.sa.base.module.support.datatracer.service.DataTracerService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
public class PickDetailServiceImpl implements PickDetailService {

    @Resource
    private ItemManager itemManager;

    @Resource
    private PickManager pickManager;

    @Resource
    private PickDetailManager pickDetailManager;

    @Resource
    private ItemQueryService itemQueryService;

    @Resource
    private PickDetailQueryService pickDetailQueryService;

    @Resource
    private DataTracerService dataTracerService;

    /**
     * 添加
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> add(PickDetailAddForm addForm) {
        PickDetailEntity pickDetailEntity = SmartBeanUtil.copy(addForm, PickDetailEntity.class);
        pickDetailManager.save(pickDetailEntity);

        //刷新出库单
        refreshPick(addForm.getPickId());

        //业务操作记录
        ItemEntity item = itemManager.queryItem(addForm.getItemId());
        dataTracerService.addTrace(pickDetailEntity.getPickId(), DataTracerTypeEnum.PICK, "添加：" + item.getItemCode() + "物料明细", null, pickDetailEntity);

        return ResponseDTO.ok();
    }

    /**
     * 更新
     */
    public ResponseDTO<String> update(PickDetailUpdateForm updateForm) {
        PickDetailEntity originEntity = pickDetailManager.getById(updateForm.getPickDetailId());
        PickDetailEntity pickDetailEntity = SmartBeanUtil.copy(updateForm, PickDetailEntity.class);
        pickDetailManager.updateById(pickDetailEntity);

        //刷新出库单
        refreshPick(updateForm.getPickId());

        ItemEntity item = itemManager.queryItem(updateForm.getItemId());
        dataTracerService.addTrace(pickDetailEntity.getPickId(), DataTracerTypeEnum.PICK, "编辑：" + item.getItemCode() + "物料明细", originEntity, pickDetailEntity);

        return ResponseDTO.ok();
    }

    /**
     * 批量删除
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> batchDelete(List<Long> idList) {
        if (CollectionUtils.isEmpty(idList)) {
            return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
        }
        //消息提示
        JoinerResult resultMsg = JoinerResult.createJoiner();

        //查询出库明细
        List<PickDetailEntity> pickDetails = pickDetailQueryService.queryByPickDetailIds(idList);

        //获取出库明细去重后的入库单ID集合
        List<Long> pickIds = pickDetails.stream().filter(Objects::nonNull).map(PickDetailEntity::getPickId).distinct().toList();

        //获取物料id集合
        List<Long> itemIds = pickDetails.stream().map(PickDetailEntity::getItemId).toList();

        //查询物料
        Map<Long, ItemEntity> mapItem = itemQueryService.queryByItemIdsToMap(itemIds);

        List<Long> toDeleteList = new ArrayList<>();
        for (PickDetailEntity pickDetail : pickDetails) {
            ItemEntity item = mapItem.get(pickDetail.getItemId());

            if (pickDetail.getAllocatedQuantity().compareTo(BigDecimal.ZERO) > 0) {
                resultMsg.getErrorMsg().add(item.getItemCode() + "明细已分配");
                continue;
            }
            toDeleteList.add(pickDetail.getPickDetailId());
            resultMsg.getSussMsg().add(item.getItemCode() + "明细删除成功");
        }

        if (CollectionUtils.isNotEmpty(toDeleteList)) {
            //批量删除
            pickDetailManager.removeBatchByIds(toDeleteList);
            //操作记录
            dataTracerService.addTrace(pickIds.get(0), DataTracerTypeEnum.PICK, "批量删除：" + resultMsg.getSussMsg().toString() + resultMsg.getErrorMsg().toString());
        }

        //刷新出库单
        pickIds.forEach(this::refreshPick);

        return ResponseDTOUtil.buildResponseDTO(resultMsg);
    }

    /**
     * 单个删除
     */
    public ResponseDTO<String> delete(Long pickDetailId) {
        if (null == pickDetailId) {
            return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
        }
        //消息提示
        JoinerResult resultMsg = JoinerResult.createJoiner();

        //出库明细
        PickDetailEntity pickDetail = pickDetailManager.getById(pickDetailId);

        //物料
        ItemEntity item = itemManager.queryItem(pickDetail.getItemId());

        if (pickDetail.getAllocatedQuantity().compareTo(BigDecimal.ZERO) > 0) {
            resultMsg.getErrorMsg().add(item.getItemCode() + "明细已分配");
            return ResponseDTOUtil.buildResponseDTO(resultMsg);
        }

        Long pickId = pickDetail.getPickId();
        pickDetailManager.removeById(pickDetailId);
        resultMsg.getSussMsg().add(item.getItemCode() + "删除成功");

        //刷新出库单
        refreshPick(pickId);

        //操作记录
        dataTracerService.addTrace(pickId, DataTracerTypeEnum.PICK, "删除：" + resultMsg.getSussMsg().toString() + resultMsg.getErrorMsg().toString());


        return ResponseDTOUtil.buildResponseDTO(resultMsg);
    }

    public void refreshPick(Long pickId) {
        //出库单
        PickEntity pick = pickManager.getById(pickId);

        //获取订单明细
        List<PickDetailEntity> pickDetails = pickDetailQueryService.queryPickDetailByPickId(pickId);

        //订单数量
        BigDecimal orderQuantity = pickDetails.stream().map(PickDetailEntity::getOrderQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);

        //分配数量
        BigDecimal allocatedQuantity = pickDetails.stream().map(PickDetailEntity::getAllocatedQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);

        //拣货数量
        BigDecimal pickedQuantity = pickDetails.stream().map(PickDetailEntity::getPickedQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);


        //当前状态
        String status = pick.getStatus();
        if (orderQuantity.compareTo(BigDecimal.ZERO) >= 0 && allocatedQuantity.compareTo(BigDecimal.ZERO) == 0  && pickedQuantity.compareTo(BigDecimal.ZERO) == 0) {
            status = PickOrderStatusEnum.CREATED.getValue();
        } else if (SmartBigDecimalUtil.subtract(orderQuantity, allocatedQuantity, 2).compareTo(BigDecimal.ZERO) > 0 && allocatedQuantity.compareTo(BigDecimal.ZERO) > 0 && pickedQuantity.compareTo(BigDecimal.ZERO) == 0) {
            status = PickOrderStatusEnum.PARTIALLY_ALLOCATED.getValue();
        } else if (SmartBigDecimalUtil.subtract(orderQuantity, allocatedQuantity, 2).compareTo(BigDecimal.ZERO) == 0 && allocatedQuantity.compareTo(BigDecimal.ZERO) > 0 && pickedQuantity.compareTo(BigDecimal.ZERO) == 0) {
            status = PickOrderStatusEnum.ALLOCATED.getValue();
        }else if(SmartBigDecimalUtil.subtract(orderQuantity, pickedQuantity, 2).compareTo(BigDecimal.ZERO) > 0 && allocatedQuantity.compareTo(BigDecimal.ZERO) > 0 && pickedQuantity.compareTo(BigDecimal.ZERO) > 0){
            status = PickOrderStatusEnum.PARTIALLY_PICKED.getValue();
        }else if(SmartBigDecimalUtil.subtract(orderQuantity, pickedQuantity, 2).compareTo(BigDecimal.ZERO) == 0 && allocatedQuantity.compareTo(BigDecimal.ZERO) > 0 && pickedQuantity.compareTo(BigDecimal.ZERO) > 0){
            status = PickOrderStatusEnum.COMPLETED.getValue();
        }

        pick.setOrderQuantity(orderQuantity);
        pick.setAllocatedQuantity(allocatedQuantity);
        pick.setPickedQuantity(pickedQuantity);
        pick.setStatus(status);
        pickManager.updateById(pick);

    }
}
