package cn.iocoder.foodnexus.module.operations.service.inquireprice;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.foodnexus.framework.common.util.CommonUtil;
import cn.iocoder.foodnexus.module.erp.dal.dataobject.product.ProductSupplierDO;
import cn.iocoder.foodnexus.module.erp.dal.dataobject.sale.ErpCustomerDO;
import cn.iocoder.foodnexus.module.erp.service.product.ProductSupplierService;
import cn.iocoder.foodnexus.module.erp.service.sale.ErpCustomerService;
import cn.iocoder.foodnexus.module.operations.controller.admin.inquirecustomerpush.vo.InquireCustomerPushSaveReqVO;
import cn.iocoder.foodnexus.module.operations.controller.admin.inquiresupplierpush.vo.InquireSupplierPushSaveReqVO;
import cn.iocoder.foodnexus.module.operations.dal.dataobject.inquirepriceitem.InquirePriceItemDO;
import cn.iocoder.foodnexus.module.operations.service.inquirecustomerpush.InquireCustomerPushService;
import cn.iocoder.foodnexus.module.operations.service.inquirepriceitem.InquirePriceItemService;
import cn.iocoder.foodnexus.module.operations.service.inquiresupplierpush.InquireSupplierPushService;
import cn.iocoder.foodnexus.module.product.api.ProductSpuApi;
import cn.iocoder.foodnexus.module.product.service.spu.ProductSpuService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import cn.iocoder.foodnexus.module.operations.controller.admin.inquireprice.vo.*;
import cn.iocoder.foodnexus.module.operations.dal.dataobject.inquireprice.InquirePriceDO;
import cn.iocoder.foodnexus.framework.common.pojo.PageResult;
import cn.iocoder.foodnexus.framework.common.pojo.PageParam;
import cn.iocoder.foodnexus.framework.common.util.object.BeanUtils;

import cn.iocoder.foodnexus.module.operations.dal.mysql.inquireprice.InquirePriceMapper;

import static cn.iocoder.foodnexus.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.foodnexus.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.foodnexus.framework.common.util.collection.CollectionUtils.diffList;
import static cn.iocoder.foodnexus.module.operations.enums.ErrorCodeConstants.*;

/**
 * 询价管理 Service 实现类
 *
 * @author 超级管理员
 */
@Service
@Validated
@Slf4j
public class InquirePriceServiceImpl implements InquirePriceService {

    @Resource
    private InquirePriceMapper inquirePriceMapper;

    @Autowired
    private InquirePriceItemService inquirePriceItemService;

    @Autowired
    private InquireSupplierPushService supplierPushService;

    @Autowired
    private ProductSupplierService productSupplierService;

    @Autowired
    private ProductSpuService productSpuService;

    @Autowired
    private InquireCustomerPushService customerPushService;

    @Autowired
    private ErpCustomerService customerService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createInquirePrice(InquirePriceSaveReqVO createReqVO) {
        // 插入
        InquirePriceDO inquirePrice = BeanUtils.toBean(createReqVO, InquirePriceDO.class);
        inquirePrice.setIsPush(Boolean.FALSE);
        inquirePriceMapper.insert(inquirePrice);

        inquirePriceItemService.addOrUpdateBatch(inquirePrice.getId(), createReqVO.getItems(), Boolean.FALSE);

        // 返回
        return inquirePrice.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateInquirePrice(InquirePriceSaveReqVO updateReqVO) {
        // 校验存在
        InquirePriceDO inquirePriceDO = validateInquirePriceExists(updateReqVO.getId());
        if (inquirePriceDO.getIsPush()) {
            throw exception("询价已推送，无法修改");
        }
        // 更新
        InquirePriceDO updateObj = BeanUtils.toBean(updateReqVO, InquirePriceDO.class);
        inquirePriceMapper.updateById(updateObj);

        inquirePriceItemService.addOrUpdateBatch(updateObj.getId(), updateReqVO.getItems(), Boolean.TRUE);
    }

    @Override
    public void deleteInquirePrice(Long id) {
        // 校验存在
        validateInquirePriceExists(id);
        // 删除
        inquirePriceMapper.deleteById(id);
    }

    @Override
        public void deleteInquirePriceListByIds(List<Long> ids) {
        // 删除
        inquirePriceMapper.deleteByIds(ids);
        }


    private InquirePriceDO validateInquirePriceExists(Long id) {
        InquirePriceDO inquirePriceDO = inquirePriceMapper.selectById(id);
        if (inquirePriceDO == null) {
            throw exception(INQUIRE_PRICE_NOT_EXISTS);
        }
        return inquirePriceDO;
    }

    @Override
    public InquirePriceDO getInquirePrice(Long id) {
        return inquirePriceMapper.selectById(id);
    }

    @Override
    public PageResult<InquirePriceDO> getInquirePricePage(InquirePricePageReqVO pageReqVO) {
        return inquirePriceMapper.selectPage(pageReqVO);
    }

    /**
     * 推送询价
     *
     * @param pushReqVO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void pushInquirePrice(InquirePricePushReqVO pushReqVO) {
        InquirePriceDO inquirePriceDO = validateInquirePriceExists(pushReqVO.getId());
        if (inquirePriceDO.getIsPush()) {
            throw exception(INQUIRE_PRICE_PUSHED);
        }

        // 修改状态
        inquirePriceMapper.update(Wrappers.<InquirePriceDO>lambdaUpdate()
                .set(InquirePriceDO::getIsPush, Boolean.TRUE)
                .eq(InquirePriceDO::getId, pushReqVO.getId()));

        // 客户推送处理
        List<InquireCustomerPushSaveReqVO> inquireCustomerPushSaveReqVOS = CommonUtil.listConvert(pushReqVO.getCustomerIdList(), customerId -> {
            ErpCustomerDO customer = customerService.getCustomer(customerId);
            if (CommonUtil.isEmpty(customer)) {
                throw exception(INQUIRE_PRICE_CUSTOMER_NOT_EXISTS);
            }
            InquireCustomerPushSaveReqVO customerPush = new InquireCustomerPushSaveReqVO();
            customerPush.setCustomerId(customerId);
            customerPush.setInquirePriceId(pushReqVO.getId());
            customerPush.setConfirm(Boolean.FALSE);
            return customerPush;
        });
        customerPushService.addBatch(inquireCustomerPushSaveReqVOS);

        // 供应商推送
        List<InquirePriceItemDO> inquireItemList = inquirePriceItemService.queryByInquireId(pushReqVO.getId());
        // 根据询价商品绑定的供应商分组
        Map<Long, InquirePriceItemDO> productToItemMap = CommonUtil.listConvertMap(inquireItemList, InquirePriceItemDO::getProductId);
        Map<Long, List<ProductSupplierDO>> supplierGroupMap =
                productSupplierService.groupBySupplierId(productToItemMap.keySet());

        if (CommonUtil.isNotEmpty(supplierGroupMap)) {
            List<InquireSupplierPushSaveReqVO> totalSupplierPush = new ArrayList<>();
            supplierGroupMap.forEach((supplierId, items) -> {
                for (ProductSupplierDO productSupplier : items) {
                    InquirePriceItemDO inquirePriceItemDO = productToItemMap.get(productSupplier.getProductId());
                    InquireSupplierPushSaveReqVO supplierPush = new InquireSupplierPushSaveReqVO();
                    supplierPush.setSupplierId(supplierId);
                    supplierPush.setInquirePriceId(pushReqVO.getId());
                    supplierPush.setInquirePriceItemId(inquirePriceItemDO.getId());
                    supplierPush.setProductId(productSupplier.getProductId());
                    supplierPush.setCategoryId(inquirePriceItemDO.getCategoryId());
                    supplierPush.setConfirm(Boolean.FALSE);
                    totalSupplierPush.add(supplierPush);
                }
            });
            supplierPushService.addBatch(totalSupplierPush);
        }
    }

    @Override
    public List<InquirePriceDO> getInquirePrice(List<Long> collect) {
        if (CommonUtil.isEmpty(collect)) {
            return Lists.newArrayList();
        }
        return inquirePriceMapper.selectByIds(collect);
    }
}