package cn.iocoder.yudao.module.mes.service.saleorder;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.product.ErpProductUnitService;
import cn.iocoder.yudao.module.erp.service.sale.ErpCustomerService;
import cn.iocoder.yudao.module.mes.controller.admin.saleorder.vo.SaleOrderItemsRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.saleorder.vo.SaleOrderPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.saleorder.vo.SaleOrderRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.saleorder.vo.SaleOrderSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.saleorder.SaleOrderDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.saleorder.SaleOrderItemsDO;
import cn.iocoder.yudao.module.mes.dal.mysql.saleorder.SaleOrderItemsMapper2;
import cn.iocoder.yudao.module.mes.dal.mysql.saleorder.SaleOrderMapper2;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.SALE_ORDER_ITEMS_NOT_EXISTS;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.SALE_ORDER_NOT_EXISTS;

/**
 * 销售订单 Service 实现类
 *
 * @author 内蒙必硕
 */
@Service
@Validated
public class SaleOrderServiceImpl implements SaleOrderService2 {

    @Resource
    private SaleOrderMapper2 saleOrderMapper;
    @Resource
    private SaleOrderItemsMapper2 saleOrderItemsMapper;

    @Override
    public Long createSaleOrder(SaleOrderSaveReqVO createReqVO) {
        // 插入
        SaleOrderDO saleOrder = BeanUtils.toBean(createReqVO, SaleOrderDO.class);
        saleOrderMapper.insert(saleOrder);
        // 返回
        return saleOrder.getId();
    }

    @Override
    public void updateSaleOrder(SaleOrderSaveReqVO updateReqVO) {
        // 校验存在
        validateSaleOrderExists(updateReqVO.getId());
        // 更新
        SaleOrderDO updateObj = BeanUtils.toBean(updateReqVO, SaleOrderDO.class);
        saleOrderMapper.updateById(updateObj);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteSaleOrder(Long id) {
        // 校验存在
        validateSaleOrderExists(id);
        // 删除
        saleOrderMapper.deleteById(id);

        // 删除子表
        deleteSaleOrderItemsByOrderId(id);
    }

    private void validateSaleOrderExists(Long id) {
        if (saleOrderMapper.selectById(id) == null) {
            throw exception(SALE_ORDER_NOT_EXISTS);
        }
    }

    @Override
    public SaleOrderDO getSaleOrder(Long id) {
        return saleOrderMapper.selectById(id);
    }

    @Override
    public PageResult<SaleOrderRespVO> getSaleOrderPage(SaleOrderPageReqVO pageReqVO) {
        PageResult<SaleOrderDO> pageResult = saleOrderMapper.selectPage(pageReqVO);
        return new PageResult<>(buildVOList(pageResult.getList()), pageResult.getTotal());
    }

    private List<SaleOrderRespVO> buildVOList(List<SaleOrderDO> list) {
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        Map<Long, ErpCustomerDO> map = customerService.getCustomerMap(
                convertSet(list, SaleOrderDO::getCustomerId));

        return BeanUtils.toBean(list, SaleOrderRespVO.class, item -> {
            MapUtils.findAndThen(map, item.getCustomerId(),
                    doEntity -> item.setCustomerName(doEntity.getName()));
        });
    }

    @Resource
    private ErpCustomerService customerService;
    // ==================== 子表（销售订单项） ====================
    @Resource
    private ErpProductService productService;
    @Resource
    private ErpProductUnitService productUnitService;

    @Override
    public PageResult<SaleOrderItemsRespVO> getSaleOrderItemsPage(PageParam pageReqVO, Long orderId) {
        PageResult<SaleOrderItemsDO> pageResult = saleOrderItemsMapper.selectPage(pageReqVO, orderId);
        return new PageResult<>(buildDetailVOList(pageResult.getList()), pageResult.getTotal());
    }

    private List<SaleOrderItemsRespVO> buildDetailVOList(List<SaleOrderItemsDO> list) {
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        Map<Long, ErpProductDO> map = productService.getProductMap(
                convertSet(list, SaleOrderItemsDO::getProductId));
        Map<Long, ErpProductUnitDO> unitMap = productUnitService.getProductUnitMap(
                convertSet(list, SaleOrderItemsDO::getProductUnitId));

        return BeanUtils.toBean(list, SaleOrderItemsRespVO.class, item -> {
            MapUtils.findAndThen(map, item.getProductId(),
                    product -> item.setProductName(product.getName()));
            MapUtils.findAndThen(unitMap, item.getProductUnitId(),
                    unit -> item.setUnitName(unit.getName()));
        });
    }

    @Override
    public Long createSaleOrderItems(SaleOrderItemsDO saleOrderItems) {
        saleOrderItemsMapper.insert(saleOrderItems);
        return saleOrderItems.getId();
    }

    @Override
    public void updateSaleOrderItems(SaleOrderItemsDO saleOrderItems) {
        // 校验存在
        validateSaleOrderItemsExists(saleOrderItems.getId());
        // 更新
        saleOrderItemsMapper.updateById(saleOrderItems);
    }

    @Override
    public void deleteSaleOrderItems(Long id) {
        // 校验存在
        validateSaleOrderItemsExists(id);
        // 删除
        saleOrderItemsMapper.deleteById(id);
    }

    @Override
    public SaleOrderItemsDO getSaleOrderItems(Long id) {
        return saleOrderItemsMapper.selectById(id);
    }

    private void validateSaleOrderItemsExists(Long id) {
        if (saleOrderItemsMapper.selectById(id) == null) {
            throw exception(SALE_ORDER_ITEMS_NOT_EXISTS);
        }
    }

    private void deleteSaleOrderItemsByOrderId(Long orderId) {
        saleOrderItemsMapper.deleteByOrderId(orderId);
    }

    @Override
    public List<SaleOrderItemsRespVO> getSaleOrderItemsByOrderId(Long orderId) {
        List<SaleOrderItemsDO> list = saleOrderItemsMapper.selectList(SaleOrderItemsDO::getOrderId, orderId);

        return buildDetailVOList(list);
    }
}