package net.lab1024.sa.admin.module.business.receive.asnDetail.service;

import java.math.BigDecimal;
import java.util.*;

import net.lab1024.sa.admin.module.business.base.item.dao.ItemDao;
import net.lab1024.sa.admin.module.business.base.item.domain.entity.ItemEntity;
import net.lab1024.sa.admin.module.business.base.item.service.ItemQueryService;
import net.lab1024.sa.admin.module.business.base.item.service.ItemService;
import net.lab1024.sa.admin.module.business.receive.asn.constant.AsnOrderStatusEnum;
import net.lab1024.sa.admin.module.business.receive.asn.dao.AsnDao;
import net.lab1024.sa.admin.module.business.receive.asn.domain.entity.AsnEntity;
import net.lab1024.sa.admin.module.business.receive.asnDetail.dao.AsnDetailDao;
import net.lab1024.sa.admin.module.business.receive.asnDetail.domain.entity.AsnDetailEntity;
import net.lab1024.sa.admin.module.business.receive.asnDetail.domain.form.AsnDetailAddForm;
import net.lab1024.sa.admin.module.business.receive.asnDetail.domain.form.AsnDetailUpdateForm;
import net.lab1024.sa.admin.module.business.receive.asnDetail.manager.AsnDetailManager;
import net.lab1024.sa.admin.util.JoinerResult;
import net.lab1024.sa.admin.util.ResponseDTOUtils;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartBigDecimalUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import jakarta.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;

/**
 * 入库明细 Service
 *
 * @author 霍锦
 * @since 2025-03-26 15:16:28
 * copyright 友仓
 */

@Service
public class AsnDetailService {

    @Resource
    private AsnDao asnDao;

    @Resource
    private ItemDao itemDao;

    @Resource
    private AsnDetailDao asnDetailDao;

    @Resource
    private AsnDetailManager asnDetailManager;

    @Resource
    private ItemQueryService itemQueryService;

    @Resource
    private AsnDetailQueryService asnDetailQueryService;


    /**
     * 添加
     *
     * @param addForm 添加表单
     * @return ResponseDTO<String>
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> add(AsnDetailAddForm addForm) {
        AsnDetailEntity asnDetailEntity = SmartBeanUtil.copy(addForm, AsnDetailEntity.class);
        asnDetailDao.insert(asnDetailEntity);
        //刷新出库单
        refreshAsn(addForm.getAsnId());
        return ResponseDTO.ok();
    }

    /**
     * 更新
     *
     * @param updateForm 更新表单
     * @return ResponseDTO<String>
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> update(AsnDetailUpdateForm updateForm) {
        AsnDetailEntity asnDetailEntity = SmartBeanUtil.copy(updateForm, AsnDetailEntity.class);
        asnDetailDao.updateById(asnDetailEntity);
        //刷新出库单
        refreshAsn(updateForm.getAsnId());
        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 joiner = JoinerResult.createJoiner();
        Set<Long> asnIds = new HashSet<>();
        List<Long> toDeleteList = new ArrayList<>();
        List<AsnDetailEntity> asnDetails = asnDetailQueryService.queryAsnDetailList(idList);
        List<Long> itemIds = asnDetails.stream().map(AsnDetailEntity::getItemId).toList();
        Map<Long, ItemEntity> mapItem = itemQueryService.queryItemList(itemIds);
        for (AsnDetailEntity asnDetail : asnDetails) {
            ItemEntity item = mapItem.get(asnDetail.getItemId());
            if (asnDetail.getReceivedQuantity().compareTo(BigDecimal.ZERO) > 0) {
                joiner.getErrorMsg().add(item.getItemCode() + "明细已收货");
                continue;
            }
            toDeleteList.add(asnDetail.getAsnDetailId());
            asnIds.add(asnDetail.getAsnId());
            joiner.getSussMsg().add(item.getItemCode() + "明细删除成功");
        }

        if (CollectionUtils.isNotEmpty(toDeleteList)) {
            //批量删除
            asnDetailManager.removeBatchByIds(toDeleteList);
        }

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

        return ResponseDTOUtils.buildResponseDTO(joiner);
    }

    /**
     * 单个删除
     *
     * @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 joiner = JoinerResult.createJoiner();
        AsnDetailEntity asnDetail = asnDetailDao.selectById(asnDetailId);
        ItemEntity item = itemDao.selectById(asnDetail.getItemId());
        if (asnDetail.getReceivedQuantity().compareTo(BigDecimal.ZERO) > 0) {
            joiner.getErrorMsg().add(item.getItemCode() + "明细已收货");
            return ResponseDTOUtils.buildResponseDTO(joiner);
        }

        Long asnId = asnDetail.getAsnId();
        asnDetailDao.deleteById(asnDetailId);
        joiner.getSussMsg().add(item.getItemCode() + "删除成功");

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

        return ResponseDTOUtils.buildResponseDTO(joiner);
    }

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

        //获取订单明细
        List<AsnDetailEntity> asnDetails = asnDetailQueryService.queryByAsnId(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) {
            status = AsnOrderStatusEnum.IN_PROGRESS.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);
        asnDao.updateById(asn);

    }
}
