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

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.foodnexus.framework.common.enums.CommonStatusEnum;
import cn.iocoder.foodnexus.framework.common.pojo.ImportResult;
import cn.iocoder.foodnexus.framework.common.util.CommonUtil;
import cn.iocoder.foodnexus.framework.common.util.json.JsonUtils;
import cn.iocoder.foodnexus.framework.common.util.validation.ValidationUtils;
import cn.iocoder.foodnexus.module.erp.api.enums.ErpAuditStatus;
import cn.iocoder.foodnexus.module.erp.dal.dataobject.product.ProductSupplierDO;
import cn.iocoder.foodnexus.module.erp.dal.dataobject.purchase.ErpSupplierDO;
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.purchase.ErpSupplierService;
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.inquirepriceitem.vo.InquirePriceItemImportVO;
import cn.iocoder.foodnexus.module.operations.controller.admin.inquirepriceitem.vo.InquirePriceItemSaveReqVO;
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.dal.dataobject.category.ProductCategoryDO;
import cn.iocoder.foodnexus.module.product.dal.dataobject.spu.ProductSpuDO;
import cn.iocoder.foodnexus.module.product.dal.mysql.category.ProductCategoryMapper;
import cn.iocoder.foodnexus.module.product.dal.mysql.spu.ProductSpuMapper;
import cn.iocoder.foodnexus.module.product.service.category.ProductCategoryService;
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.erp.enums.ErrorCodeConstants.SUPPLIER_NOT_ENABLE;
import static cn.iocoder.foodnexus.module.erp.enums.ErrorCodeConstants.SUPPLIER_NOT_EXISTS;
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 ErpSupplierService supplierService;

    @Autowired
    private InquireCustomerPushService customerPushService;

    @Autowired
    private ErpCustomerService customerService;

    @Autowired
    private ProductSpuMapper productMapper;

    @Autowired
    private ProductCategoryMapper productCategoryMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createInquirePrice(InquirePriceSaveReqVO createReqVO) {
        // 插入
        InquirePriceDO inquirePrice = BeanUtils.toBean(createReqVO, InquirePriceDO.class);
        inquirePrice.setIsPush(Boolean.FALSE);
        if (CommonUtil.isNotEmpty(createReqVO.getInquiryYearMonth())) {
            createReqVO.setInquiryYearMonth(createReqVO.getInquiryYearMonth().length() >= 7 ? createReqVO.getInquiryYearMonth().substring(0, 7) : createReqVO.getInquiryYearMonth());
        }
        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("询价已推送，无法修改");
        }
        if (CommonUtil.isNotEmpty(updateReqVO.getInquiryYearMonth())) {
            updateReqVO.setInquiryYearMonth(updateReqVO.getInquiryYearMonth().length() >= 7 ? updateReqVO.getInquiryYearMonth().substring(0, 7) : updateReqVO.getInquiryYearMonth());
        }
        // 更新
        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) {
                    ErpSupplierDO supplier = supplierService.getSupplier(supplierId);
                    if (CommonUtil.isNotEmpty(supplier) && String.valueOf(ErpAuditStatus.APPROVE.getStatus()).equals(supplier.getAuditStatus()) &&  CommonStatusEnum.isEnable(supplier.getStatus())) {
                        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.TRUE);
                        supplierPush.setSupplierQuote(inquirePriceItemDO.getFloatingPrice());
                        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);
    }

    @Override
    public ImportResult<InquirePriceItemSaveReqVO> importItems(List<InquirePriceItemImportVO> list) {
        if (CommonUtil.isEmpty(list)) {
            return new ImportResult<InquirePriceItemSaveReqVO>().setTotalCount(0);
        }
        int totalCount = 0;
        int successCount = 0;
        int errorCount = 0;
        ImportResult<InquirePriceItemSaveReqVO> result = new ImportResult<>();

        // 根据商品名称查询
        List<ProductSpuDO> productSpuList = productMapper.selectList(Wrappers.<ProductSpuDO>lambdaQuery()
                .in(ProductSpuDO::getName, CommonUtil.listConvertSet(list, i -> i.getProductName().trim())));
        Map<String, ProductSpuDO> productMap = CommonUtil.listConvertMap(productSpuList, ProductSpuDO::getName);

        List<ProductCategoryDO> productCategoryDOS = productCategoryMapper.selectList(Wrappers.<ProductCategoryDO>lambdaQuery()
                .in(ProductCategoryDO::getName, CommonUtil.listConvertSet(list, InquirePriceItemImportVO::getCategoryName)));
        Map<String, ProductCategoryDO> categoryMap = CommonUtil.listConvertMap(productCategoryDOS, ProductCategoryDO::getName);
        Map<Long, ProductCategoryDO> categoryIdMap = CommonUtil.listConvertMap(productCategoryDOS, ProductCategoryDO::getId);

        // 根据分类查询

        for (InquirePriceItemImportVO item : list) {
            totalCount ++;
            try {
                ValidationUtils.validate(item);
            } catch (Exception e) {
                errorCount ++;
                result.putError(totalCount, "参数空缺", JsonUtils.toJsonString(item));
                continue;
            }
            InquirePriceItemSaveReqVO saveReq = new InquirePriceItemSaveReqVO();
            // 商品名称查询
            String productName = item.getProductName().trim();
            String categoryName = item.getCategoryName().trim();
            if (!categoryMap.containsKey(categoryName)) {
                errorCount ++;
                result.putError(totalCount, String.format("未查询到对应分类【%s】", categoryName), JsonUtils.toJsonString(item));
                continue;
            }
            if (!productMap.containsKey(productName)) {
                errorCount ++;
                result.putError(totalCount, String.format("未查询到对应商品【%s】", productName), JsonUtils.toJsonString(item));
                continue;
            } else {
                ProductSpuDO productSpuDO = productMap.get(productName);
                if (!categoryIdMap.containsKey(productSpuDO.getCategoryId())) {
                    errorCount ++;
                    result.putError(totalCount, String.format("分类【%s】下未查询到商品【%s】", categoryName, productName), JsonUtils.toJsonString(item));
                    continue;
                }
                ProductCategoryDO category = categoryIdMap.get(productSpuDO.getCategoryId());
                saveReq.setProductId(productSpuDO.getId());
                saveReq.setProductName(productSpuDO.getName());
                saveReq.setCategoryId(category.getId());
                saveReq.setCategoryName(category.getName());
                saveReq.setProductStandard(productSpuDO.getIntroduction());
                saveReq.setProductUnit(productSpuDO.getUnitName());
                // 处理价格
                try {
                    // 将String转换为double
                    double value = Double.parseDouble(item.getMarketPrice());
                    // 乘以100
                    double multiplied = value * 100;
                    // 转换为int，自动舍弃小数部分
                    saveReq.setMarketPrice((int) multiplied);
                } catch (NumberFormatException e) {
                    errorCount ++;
                    result.putError(totalCount, String.format("商品【%s】市场均价转换失败", productName), JsonUtils.toJsonString(item));
                    continue;
                }
                result.add(saveReq);
                successCount ++;
            }
            result.setTotalCount(totalCount);
            result.setErrorCount(errorCount);
            result.setSuccessCount(successCount);
        }
        return result;
    }

}