package net.lab1024.sa.admin.module.business.wms.receive.asnDetail.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.receive.asn.constant.AsnOrderStatusEnum;
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.entity.AsnEntity;
import net.lab1024.sa.admin.module.business.wms.receive.asn.manager.AsnManager;
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.entity.AsnDetailEntity;
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.form.AsnDetailAddForm;
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.form.AsnDetailUpdateForm;
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.manager.AsnDetailManager;
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.service.AsnDetailQueryService;
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.service.AsnDetailService;
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 AsnDetailServiceImpl implements AsnDetailService {

    @Resource
    private AsnManager asnManager;

    @Resource
    private ItemManager itemManager;

    @Resource
    private AsnDetailManager asnDetailManager;

    @Resource
    private ItemQueryService itemQueryService;

    @Resource
    private AsnDetailQueryService asnDetailQueryService;

    @Resource
    private DataTracerService dataTracerService;


    /**
     * 添加
     *
     * @param addForm 添加表单
     * @return ResponseDTO<String>
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> add(AsnDetailAddForm addForm) {
        AsnDetailEntity asnDetailEntity = SmartBeanUtil.copy(addForm, AsnDetailEntity.class);
        asnDetailManager.save(asnDetailEntity);

        //刷新出库单
        refreshAsn(addForm.getAsnId());

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


        return ResponseDTO.ok();
    }

    /**
     * 更新
     *
     * @param updateForm 更新表单
     * @return ResponseDTO<String>
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> update(AsnDetailUpdateForm updateForm) {
        AsnDetailEntity originEntity = asnDetailManager.getById(updateForm.getAsnDetailId());
        AsnDetailEntity asnDetailEntity = SmartBeanUtil.copy(updateForm, AsnDetailEntity.class);
        asnDetailManager.updateById(asnDetailEntity);

        //刷新出库单
        refreshAsn(updateForm.getAsnId());

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

        return ResponseDTO.ok();
    }

    /**
     * 批量删除
     *
     * @param idList id集合
     * @return ResponseDTO<String>
     */

    @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<AsnDetailEntity> asnDetails = asnDetailQueryService.queryByAsnDetailIds(idList);
        //获取入库明细去重后的入库单D集合
        List<Long> asnIds = asnDetails.stream().filter(Objects::nonNull).map(AsnDetailEntity::getAsnId).distinct().toList();
        //获取物料id集合
        List<Long> itemIds = asnDetails.stream().map(AsnDetailEntity::getItemId).toList();
        //查询物料
        Map<Long, ItemEntity> mapItem = itemQueryService.queryByItemIdsToMap(itemIds);
        List<Long> toDeleteList = new ArrayList<>();
        for (AsnDetailEntity asnDetail : asnDetails) {
            ItemEntity item = mapItem.get(asnDetail.getItemId());
            if (asnDetail.getReceivedQuantity().compareTo(BigDecimal.ZERO) > 0) {
                resultMsg.getErrorMsg().add(item.getItemCode() + "明细已收货");
                continue;
            }
            toDeleteList.add(asnDetail.getAsnDetailId());
            resultMsg.getSussMsg().add(item.getItemCode() + "明细删除成功");
        }

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

        //刷新出库单
        asnIds.forEach(this::refreshAsn);

        return ResponseDTOUtil.buildResponseDTO(resultMsg);
    }

    /**
     * 单个删除
     *
     * @param asnDetailId id
     * @return ResponseDTO<String>
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> delete(Long asnDetailId) {
        if (null == asnDetailId) {
            return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
        }
        JoinerResult resultMsg = JoinerResult.createJoiner();
        AsnDetailEntity asnDetail = asnDetailManager.getById(asnDetailId);
        ItemEntity item = itemManager.queryItem(asnDetail.getItemId());
        if (asnDetail.getReceivedQuantity().compareTo(BigDecimal.ZERO) > 0) {
            resultMsg.getErrorMsg().add(item.getItemCode() + "明细已收货");
            return ResponseDTOUtil.buildResponseDTO(resultMsg);
        }

        Long asnId = asnDetail.getAsnId();
        asnDetailManager.removeById(asnDetailId);
        resultMsg.getSussMsg().add(item.getItemCode() + "删除成功");

        //刷新出库单
        refreshAsn(asnId);

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


        return ResponseDTOUtil.buildResponseDTO(resultMsg);
    }

    public void refreshAsn(Long asnId) {
        //入库单
        AsnEntity asn = asnManager.getById(asnId);

        //获取订单明细
        List<AsnDetailEntity> asnDetails = asnDetailQueryService.queryAsnDetailByAsnId(asnId);

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

        //收货数量
        BigDecimal receivedQuantity = asnDetails.stream().map(AsnDetailEntity::getReceivedQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);

        //当前状态
        String status = asn.getStatus();
        if (orderQuantity.compareTo(BigDecimal.ZERO) >= 0 && receivedQuantity.compareTo(BigDecimal.ZERO) == 0) {
            status = AsnOrderStatusEnum.CREATED.getValue();
        } else if (SmartBigDecimalUtil.subtract(orderQuantity, receivedQuantity, 2).compareTo(BigDecimal.ZERO) > 0 && receivedQuantity.compareTo(BigDecimal.ZERO) > 0) {
            status = AsnOrderStatusEnum.PARTIALLY_IN.getValue();
        } else if (SmartBigDecimalUtil.subtract(orderQuantity, receivedQuantity, 2).compareTo(BigDecimal.ZERO) == 0 && receivedQuantity.compareTo(BigDecimal.ZERO) > 0) {
            status = AsnOrderStatusEnum.COMPLETED.getValue();
        }

        asn.setOrderQuantity(orderQuantity);
        asn.setReceivedQuantity(receivedQuantity);
        asn.setStatus(status);
        asnManager.updateById(asn);

    }
}
