package net.lab1024.sa.admin.module.business.wms.receive.asn.service.impl;

import jakarta.annotation.Resource;
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.domain.form.AsnAddForm;
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.form.AsnUpdateForm;
import net.lab1024.sa.admin.module.business.wms.receive.asn.manager.AsnManager;
import net.lab1024.sa.admin.module.business.wms.receive.asn.service.AsnQueryService;
import net.lab1024.sa.admin.module.business.wms.receive.asn.service.AsnService;
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.entity.AsnDetailEntity;
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.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.exception.BusinessException;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum;
import net.lab1024.sa.base.module.support.datatracer.service.DataTracerService;
import net.lab1024.sa.base.module.support.serialnumber.constant.SerialNumberIdEnum;
import net.lab1024.sa.base.module.support.serialnumber.service.SerialNumberService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class AsnServiceImpl implements AsnService {

    @Resource
    private AsnManager asnManager;

    @Resource
    private AsnDetailManager asnDetailManager;

    @Resource
    private AsnQueryService asnQueryService;

    @Resource
    private AsnDetailQueryService asnDetailQueryService;

    @Resource
    private SerialNumberService serialNumberService;

    @Resource
    private DataTracerService dataTracerService;

    /**
     * 添加
     *
     * @param addForm 添加参数
     * @return ResponseDTO<String>
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<AsnEntity> add(AsnAddForm addForm) {
        AsnEntity exitAsn = asnQueryService.queryByCustomerNumber(addForm.getCustomerNumber());
        if (exitAsn != null) {
            throw new BusinessException(addForm.getCustomerNumber() + "客户订单号已存在");
        }
        //自动生成入库编号
        addForm.setAsnNumber(serialNumberService.generate(SerialNumberIdEnum.ASN));
        //默认已创建
        addForm.setStatus(AsnOrderStatusEnum.CREATED.getValue());
        AsnEntity asnEntity = SmartBeanUtil.copy(addForm, AsnEntity.class);
        asnManager.save(asnEntity);

        //操作记录
        dataTracerService.addTrace(asnEntity.getAsnId(), DataTracerTypeEnum.ASN, "新建入库单：" + asnEntity.getAsnNumber(), null, asnEntity);
        return ResponseDTO.ok(asnEntity);
    }

    /**
     * 更新
     *
     * @param updateForm 更新参数
     * @return ResponseDTO<String>
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<AsnEntity> update(AsnUpdateForm updateForm) {
        AsnEntity exitAsn = asnQueryService.queryByCustomerNumber(updateForm.getCustomerNumber());
        if (exitAsn != null && !exitAsn.getAsnId().equals(updateForm.getAsnId())) {
            throw new BusinessException(updateForm.getCustomerNumber() + "客户订单号已存在");
        }
        AsnEntity asnEntity = SmartBeanUtil.copy(updateForm, AsnEntity.class);
        asnManager.updateById(asnEntity);
        //业务操作记录
        dataTracerService.addTrace(updateForm.getAsnId(), DataTracerTypeEnum.ASN, "编辑入库单：" + asnEntity.getAsnNumber(), exitAsn, asnEntity);
        return ResponseDTO.ok(asnEntity);
    }

    /**
     * 批量删除
     *
     * @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<AsnEntity> asnList = asnQueryService.queryByAsnIds(idList);

        //将订单按状态分组；已创建的一组；非已创建的一组。
        Map<Boolean, List<AsnEntity>> partitionedAsnList = asnList.stream()
                .collect(Collectors.partitioningBy(asn -> AsnOrderStatusEnum.CREATED.getValue().equals(asn.getStatus())));
        //已创建的订单允许删除
        List<AsnEntity> createAsnList = partitionedAsnList.get(true);
        //入库单集合
        List<Long> asnIds = createAsnList.stream().map(AsnEntity::getAsnId).toList();
        //根据入库单ID集合查询入库明细
        List<AsnDetailEntity> details = asnDetailQueryService.queryAsnDetailByAsnIds(asnIds);
        if (CollectionUtils.isNotEmpty(details)) {
            asnDetailManager.removeBatchByIds(details);
        }
        if (CollectionUtils.isNotEmpty(createAsnList)) {
            Set<String> asnCodes = createAsnList.stream().map(AsnEntity::getAsnNumber).collect(Collectors.toSet());
            asnManager.removeBatchByIds(createAsnList);
            resultMsg.getSussMsg().add(asnCodes + "订单删除成功");
        }

        //非已创建的订单不允许删除
        List<AsnEntity> noCreateAsnList = partitionedAsnList.get(false);
        if (CollectionUtils.isNotEmpty(noCreateAsnList)) {
            Set<String> asnCodes = noCreateAsnList.stream().map(AsnEntity::getAsnNumber).collect(Collectors.toSet());
            resultMsg.getErrorMsg().add(asnCodes + "订单不允许删除");
        }

        return ResponseDTOUtil.buildResponseDTO(resultMsg);
    }

    /**
     * 单个删除
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> delete(Long asnId) {
        if (asnId == null) {
            return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
        }
        AsnEntity asn = asnManager.getById(asnId);
        String status = asn.getStatus();
        // 只有已创建的订单才允许删除
        if (!AsnOrderStatusEnum.CREATED.getValue().equals(status)) {
            return ResponseDTO.userErrorParam(AsnOrderStatusEnum.getDescByValue(status) + "的订单不允许删除");
        }
        List<AsnDetailEntity> details = asnDetailQueryService.queryAsnDetailByAsnId(asnId);
        if (CollectionUtils.isNotEmpty(details)) {
            asnDetailManager.removeBatchByIds(details);
        }
        asnManager.removeById(asnId);
        return ResponseDTO.ok();
    }
}
