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

import cn.iocoder.foodnexus.framework.common.util.CommonUtil;
import cn.iocoder.foodnexus.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.foodnexus.module.erp.controller.admin.sale.vo.customer.ErpCustomerSimpleRespVO;
import cn.iocoder.foodnexus.module.erp.dal.dataobject.sale.ErpCustomerDO;
import cn.iocoder.foodnexus.module.erp.dal.mysql.sale.ErpCustomerMapper;
import cn.iocoder.foodnexus.module.operations.dal.dataobject.inquirepriceitem.InquirePriceItemDO;
import cn.iocoder.foodnexus.module.operations.dal.dataobject.inquiresupplierpush.InquireSupplierPushDO;
import cn.iocoder.foodnexus.module.operations.dal.mysql.inquiresupplierpush.InquireSupplierPushMapper;
import cn.iocoder.foodnexus.module.order.api.OrderScoreApi;
import cn.iocoder.foodnexus.module.product.api.dto.CustomerVisibleProductRespDTO;
import cn.iocoder.foodnexus.module.operations.controller.app.inquirecustomerpush.vo.AppInquireCustomerPushPageReqVO;
import cn.iocoder.foodnexus.module.operations.controller.app.inquirecustomerpush.vo.AppInquireCustomerPushRespVO;
import cn.iocoder.foodnexus.module.product.api.InquireCustomerApi;
import cn.iocoder.foodnexus.module.system.dal.redis.RedisKeyConstants;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import cn.iocoder.foodnexus.module.operations.controller.admin.inquirecustomerpush.vo.*;
import cn.iocoder.foodnexus.module.operations.dal.dataobject.inquirecustomerpush.InquireCustomerPushDO;
import cn.iocoder.foodnexus.framework.common.pojo.PageResult;
import cn.iocoder.foodnexus.framework.common.util.object.BeanUtils;

import cn.iocoder.foodnexus.module.operations.dal.mysql.inquirecustomerpush.InquireCustomerPushMapper;

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.module.operations.enums.ErrorCodeConstants.*;

/**
 * 询价推送-客户 Service 实现类
 *
 * @author 超级管理员
 */
@Service
@Validated
public class InquireCustomerPushServiceImpl implements InquireCustomerPushService, InquireCustomerApi {

    @Resource
    private InquireCustomerPushMapper inquireCustomerPushMapper;

    @Autowired
    private InquireSupplierPushMapper supplierPushMapper;

    @Autowired
    private ErpCustomerMapper customerMapper;

    @Autowired
    private OrderScoreApi orderScoreApi;

    @Override
    public Long createInquireCustomerPush(InquireCustomerPushSaveReqVO createReqVO) {
        // 插入
        InquireCustomerPushDO inquireCustomerPush = BeanUtils.toBean(createReqVO, InquireCustomerPushDO.class);
        inquireCustomerPushMapper.insert(inquireCustomerPush);

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

    @Override
    public void updateInquireCustomerPush(InquireCustomerPushSaveReqVO updateReqVO) {
        // 校验存在
        validateInquireCustomerPushExists(updateReqVO.getId());
        // 更新
        InquireCustomerPushDO updateObj = BeanUtils.toBean(updateReqVO, InquireCustomerPushDO.class);
        inquireCustomerPushMapper.updateById(updateObj);
    }

    @Override
    public void deleteInquireCustomerPush(Long id) {
        // 校验存在
        validateInquireCustomerPushExists(id);
        // 删除
        inquireCustomerPushMapper.deleteById(id);
    }

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


    private void validateInquireCustomerPushExists(Long id) {
        if (inquireCustomerPushMapper.selectById(id) == null) {
            throw exception(INQUIRE_CUSTOMER_PUSH_NOT_EXISTS);
        }
    }

    @Override
    public InquireCustomerPushDO getInquireCustomerPush(Long id) {
        return inquireCustomerPushMapper.selectById(id);
    }

    @Override
    public PageResult<InquireCustomerPushDO> getInquireCustomerPushPage(InquireCustomerPushPageReqVO pageReqVO) {
        return inquireCustomerPushMapper.selectPage(pageReqVO);
    }

    /**
     * 客户确认
     *
     * @param id
     */
    @Override
    @CacheEvict(cacheNames = RedisKeyConstants.CUSTOMER_VISIBLE_PRODUCT, allEntries = true)
    public void confirm(Long id) {
        validateInquireCustomerPushExists(id);
        inquireCustomerPushMapper.update(Wrappers.<InquireCustomerPushDO>lambdaUpdate()
                .eq(InquireCustomerPushDO::getId, id)
                .set(InquireCustomerPushDO::getConfirm, Boolean.TRUE)
                .set(InquireCustomerPushDO::getConfirmUser, SecurityFrameworkUtils.getLoginUserId())
                .set(InquireCustomerPushDO::getConfirmTime, LocalDateTime.now()));
    }

    /**
     * app 端 客户查询询价
     *
     * @param pageReqVO
     * @return
     */
    @Override
    public PageResult<AppInquireCustomerPushRespVO> getAppInquireCustomerPushPage(AppInquireCustomerPushPageReqVO pageReqVO) {
        return inquireCustomerPushMapper.selectPage(pageReqVO);
    }

    @Override
    public List<ErpCustomerSimpleRespVO> getSimpCustomer(Long inquireId) {
        List<InquireCustomerPushDO> inquireCustomerPushDOS = inquireCustomerPushMapper.selectList(InquireCustomerPushDO::getInquirePriceId, inquireId);
        return CommonUtil.listConvert(inquireCustomerPushDOS, item -> {
            ErpCustomerDO customer = customerMapper.selectOne(Wrappers.<ErpCustomerDO>lambdaQuery()
                    .select(ErpCustomerDO::getId, ErpCustomerDO::getName)
                    .eq(ErpCustomerDO::getId, item.getCustomerId()));
            return BeanUtils.toBean(customer, ErpCustomerSimpleRespVO.class, i -> i.setConfirm(item.getConfirm()));
        });
    }

    @Override
    public Map<Long, List<ErpCustomerSimpleRespVO>> getSimpCustomerMap(Collection<Long> inquireIds) {
        if (CommonUtil.isEmpty(inquireIds)) {
            return new HashMap<>();
        }
        List<InquireCustomerPushDO> inquireCustomerPushDOS = inquireCustomerPushMapper.selectList(Wrappers.<InquireCustomerPushDO>lambdaQuery()
                .in(InquireCustomerPushDO::getInquirePriceId, inquireIds));
        if (CommonUtil.isEmpty(inquireCustomerPushDOS)) {
            return new HashMap<>();
        }
        return CommonUtil.listConvertListMap(inquireCustomerPushDOS, InquireCustomerPushDO::getInquirePriceId, item -> {
            ErpCustomerDO customer = customerMapper.selectOne(Wrappers.<ErpCustomerDO>lambdaQuery()
                    .select(ErpCustomerDO::getId, ErpCustomerDO::getName)
                    .eq(ErpCustomerDO::getId, item.getCustomerId()));
            return BeanUtils.toBean(customer, ErpCustomerSimpleRespVO.class, i -> i.setConfirm(item.getConfirm()));
        });
    }


    @Override
    @Cacheable(cacheNames = RedisKeyConstants.CUSTOMER_VISIBLE_PRODUCT, key = "#customerId", unless = "#result == null")
    public CustomerVisibleProductRespDTO queryCustomerIdByCustomerId(Long customerId) {
        List<InquirePriceItemDO> inquirePriceItemDOS = inquireCustomerPushMapper.queryConfirmPush(customerId);
        if (CommonUtil.isEmpty(inquirePriceItemDOS)) {
            return null;
        }
        Map<Long, List<InquirePriceItemDO>> productIdMap = CommonUtil.listConvertListMap(inquirePriceItemDOS, InquirePriceItemDO::getProductId);
        List<InquirePriceItemDO> currentItemList = new ArrayList<>();
        productIdMap.forEach((productId, list) -> {
            if (list.size() == 1) {
                currentItemList.add(list.get(0));
            } else if (list.size() > 1) {
                List<InquirePriceItemDO> collect = list.stream().filter(itemPrice ->
                        supplierPushMapper.exists(Wrappers.<InquireSupplierPushDO>lambdaQuery()
                                .eq(InquireSupplierPushDO::getInquirePriceItemId, itemPrice.getId())
                                .eq(InquireSupplierPushDO::getConfirm, Boolean.TRUE))).toList();
                if (CommonUtil.isNotEmpty(collect)) {
                    currentItemList.add(collect.stream().max(Comparator.comparing(InquirePriceItemDO::getCreateTime)).get());
                }
            }
        });


        // 查询对应供应商的报价
        List<InquireSupplierPushDO> supplierPushList = supplierPushMapper.queryQuoteByItemId(CommonUtil.listConvert(currentItemList, InquirePriceItemDO::getId));
        if (CommonUtil.isEmpty(supplierPushList)) {
            return null;
        }

        CustomerVisibleProductRespDTO dto = new CustomerVisibleProductRespDTO();

        Map<Long, List<InquireSupplierPushDO>> supplierProductMap = CommonUtil.listConvertListMap(supplierPushList, InquireSupplierPushDO::getProductId);
        Map<Long, InquirePriceItemDO> inquirePriceMap = CommonUtil.listConvertMap(inquirePriceItemDOS, InquirePriceItemDO::getId);
        supplierProductMap.forEach((productId, list) -> {
            // TODO 根据供应商评分排序等....
            if (CommonUtil.isNotEmpty(list)) {
                // InquireSupplierPushDO push = list.get(0);
                Long topRankSupplierId = orderScoreApi.queryTopSupplierRank(CommonUtil.listConvert(list, InquireSupplierPushDO::getSupplierId));
                InquireSupplierPushDO push = list.stream().filter(i -> i.getSupplierId().equals(topRankSupplierId)).findFirst().get();
                InquirePriceItemDO inquirePriceItemDO = inquirePriceMap.get(push.getInquirePriceItemId());
                dto.put(push.getId(), push.getProductId(), push.getSupplierQuote(), inquirePriceItemDO.getMarketPrice(), inquirePriceItemDO.getFloatingRate());
            }
        });

        return dto;
    }
}