package com.bonus.canteen.core.supply.purchase.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bonus.canteen.core.supply.purchase.domain.param.DrpMaterialSupplierWinRecordsDTO;
import com.bonus.canteen.core.supply.purchase.domain.bo.DrpMaterialWinBidRecords;
import com.bonus.canteen.core.supply.purchase.domain.bo.MaterialAndUnitDTO;
import com.bonus.canteen.core.supply.purchase.domain.param.DrpMaterialBidRecordsPageDTO;
import com.bonus.canteen.core.supply.purchase.domain.vo.*;
import com.bonus.canteen.core.supply.purchase.mapper.DrpPurchaseMaterialWinBidRecordsMapper;
import com.bonus.canteen.core.supply.purchase.service.DrpMaterialWinBidRecordsService;
import com.bonus.common.core.exception.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class DrpMaterialWinBidRecordsServiceImpl extends ServiceImpl<DrpPurchaseMaterialWinBidRecordsMapper, DrpMaterialWinBidRecords> implements DrpMaterialWinBidRecordsService {
   @Autowired
   @Lazy
   private DrpPurchaseMaterialWinBidRecordsMapper drpPurchaseMaterialWinBidRecordsMapper;

   public List<DrpMaterialBidRecordsPageVO> pageMaterialBidRecords(DrpMaterialBidRecordsPageDTO content) {
      List<DrpMaterialBidRecordsPageVO> recordsList = this.drpPurchaseMaterialWinBidRecordsMapper.listMaterialUnit(content);
      if (CollUtil.isEmpty(recordsList)) {
         return recordsList;
      }

      try {
         // 获取供应商报价详情并按 materialId 分组
         List<Long> materialIds = recordsList.stream()
                 .map(DrpMaterialBidRecordsPageVO::getMaterialId)
                 .distinct()
                 .collect(Collectors.toList());
         List<DrpMaterialBidRecordsSupplierVO> detailList = drpPurchaseMaterialWinBidRecordsMapper.listSupplierPriceByMaterialIdList(materialIds);
         Map<Long, List<DrpMaterialBidRecordsSupplierVO>> supplierDetailMap = detailList.stream()
                 .collect(Collectors.groupingBy(DrpMaterialBidRecordsSupplierVO::getMaterialId));

         // 构建物料与单位的 DTO 列表
         List<MaterialAndUnitDTO> materialAndUnitDTOS = recordsList.stream()
                 .map(d -> {
                    MaterialAndUnitDTO dto = new MaterialAndUnitDTO();
                    dto.setMaterialId(d.getMaterialId());
                    dto.setUnitId(d.getUnitId());
                    return dto;
                 })
                 .collect(Collectors.toList());

         // 获取最近订单价格并构建 map
         List<DrpLastOrderGoodsVO> orderGoodsVOList = drpPurchaseMaterialWinBidRecordsMapper.getLastOrderGoodsPriceList(materialAndUnitDTOS, content.getAreaId());
         Map<String, DrpLastOrderGoodsVO> orderGoodsMap = orderGoodsVOList.stream()
                 .collect(Collectors.toMap(
                         d -> buildKey(d.getMaterialId(), d.getUnitId()),
                         Function.identity(),
                         (existing, replacement) -> existing));

         // 获取市场价格并构建 map
         List<DrpMarketPriceVO> marketPriceVOList = drpPurchaseMaterialWinBidRecordsMapper.getMarketPriceList(materialAndUnitDTOS, content.getAreaId());
         Map<String, List<DrpMarketPriceVO>> marketPriceMap = marketPriceVOList.stream()
                 .collect(Collectors.groupingBy(d -> buildKey(d.getMaterialId(), d.getUnitId())));

         // 填充每个记录的数据
         for (DrpMaterialBidRecordsPageVO record : recordsList) {
            // 设置供应商报价详情
            List<DrpMaterialBidRecordsSupplierVO> details = supplierDetailMap.get(record.getMaterialId());
            record.setDetailList(details);

            // 设置价格状态：1-有效，2-无效
            if (details != null) {
               List<DrpMaterialBidRecordsSupplierVO> validBids = details.stream()
                       .filter(d -> d.getBidValidityStartTime() != null && d.getBidValidityStartTime().isBefore(LocalDateTime.now()) &&
                               d.getBidValidityEndTime() != null && d.getBidValidityEndTime().isAfter(LocalDateTime.now()))
                       .collect(Collectors.toList());
               record.setPriceStatus(CollUtil.isNotEmpty(validBids) ? 1 : 2);
            }

            // 设置最近采购价信息
            String key = buildKey(record.getMaterialId(), record.getUnitId());
            DrpLastOrderGoodsVO lastOrderGoodsVO = orderGoodsMap.get(key);
            record.setDrpLastOrderGoods(lastOrderGoodsVO);

            // 设置市场价格及浮动比例
            List<DrpMarketPriceVO> prices = marketPriceMap.get(key);
            if (CollUtil.isNotEmpty(prices) && lastOrderGoodsVO != null &&
                    lastOrderGoodsVO.getLastOrderGoodsPrice() != null) {

               BigDecimal lastPrice = new BigDecimal(lastOrderGoodsVO.getLastOrderGoodsPrice());
               prices.forEach(price -> {
                  if (price.getUnitPrice() != null) {
                     BigDecimal currentPrice = new BigDecimal(price.getUnitPrice());
                     price.setFloatingRatio(lastPrice.subtract(currentPrice)
                             .multiply(new BigDecimal(100))
                             .divide(currentPrice, 2, RoundingMode.HALF_UP));
                  }
               });
            }

            record.setDrpMarketPriceList(prices);
         }

         return recordsList;
      } catch (Exception e) {
         log.error("处理价格失败", e);
         throw new ServiceException("系统错误");
      }
   }

   private String buildKey(Long materialId, Long unitId) {
      return materialId + "-" + unitId;
   }


   public List<DrpMaterialSupplierWinRecordsVO> listSupplierWinRecords(DrpMaterialSupplierWinRecordsDTO content) {
         return this.drpPurchaseMaterialWinBidRecordsMapper.listSupplierWinRecordsBySupplier(content.getSupplierId(), content.getMaterialIdList());
   }

   public DrpMaterialStoryBidPriceVO storyBidPrice(Long content) {
      List<DrpMaterialBidRecordsSupplierVO> supplierVOList = drpPurchaseMaterialWinBidRecordsMapper.listSupplierPriceByMaterialId(content);
      if (CollUtil.isEmpty(supplierVOList)) {
         return null;
      }

      DrpMaterialBidRecordsSupplierVO firstVO = supplierVOList.get(0);

      DrpMaterialStoryBidPriceVO resultVO = new DrpMaterialStoryBidPriceVO();
      resultVO.setMaterialId(content);
      resultVO.setMaterialName(firstVO.getMaterialName());
      resultVO.setMaterialCode(firstVO.getMaterialCode());
      resultVO.setUnitName(firstVO.getUnitName());
      resultVO.setCategoryName(firstVO.getCategoryName());

      Map<String, List<DrpMaterialBidRecordsSupplierVO>> inquiryGroupMap = supplierVOList.stream()
              .filter(t -> t.getMaterialInquiryId() != null)
              .collect(Collectors.groupingBy(DrpMaterialBidRecordsSupplierVO::getMaterialInquiryId));

      List<DrpMaterialStoryBidPriceVO.DrpMaterialInquiryVO> inquiryVOList = new ArrayList<>();
      if (CollUtil.isNotEmpty(inquiryGroupMap)) {
         inquiryGroupMap.forEach((key, value) -> {
            DrpMaterialStoryBidPriceVO.DrpMaterialInquiryVO inquiryVO = new DrpMaterialStoryBidPriceVO.DrpMaterialInquiryVO();
            inquiryVO.setMaterialInquiryId(key);
            inquiryVO.setBidValidityStartTime(value.get(0).getBidValidityStartTime());
            inquiryVO.setBidValidityEndTime(value.get(0).getBidValidityEndTime());

            List<DrpMaterialStoryBidPriceVO.DrpMaterialBidRecordsVO> recordsVOList = value.stream()
                    .map(this::convertToBidRecordVO)
                    .collect(Collectors.toList());

            inquiryVO.setRecordsVOList(recordsVOList);
            inquiryVOList.add(inquiryVO);
         });
      }

      resultVO.setMaterialInquiryVOList(inquiryVOList);
      return resultVO;
   }

   private DrpMaterialStoryBidPriceVO.DrpMaterialBidRecordsVO convertToBidRecordVO(DrpMaterialBidRecordsSupplierVO supplierVO) {
      DrpMaterialStoryBidPriceVO.DrpMaterialBidRecordsVO bidRecordsVO = new DrpMaterialStoryBidPriceVO.DrpMaterialBidRecordsVO();
      bidRecordsVO.setWinPrice(supplierVO.getWinPrice());
      bidRecordsVO.setWinDate(supplierVO.getWinDate());
      bidRecordsVO.setWinSupplierId(supplierVO.getWinSupplierId());
      bidRecordsVO.setWinSupplierName(supplierVO.getWinSupplierName());
      return bidRecordsVO;
   }

}
