package com.bonus.core.supermarket.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.constant.DelFlagEnum;
import com.bonus.constant.LeConstants;
import com.bonus.core.common.redis.RedisUtil;
import com.bonus.core.common.utils.TenantContextHolder;
import com.bonus.core.customer.api.CustInfoApi;
import com.bonus.core.customer.model.CustInfo;
import com.bonus.core.drp.api.DrpServiceApi;
import com.bonus.core.supermarket.constant.AppSaleModeEnum;
import com.bonus.core.supermarket.dto.*;
import com.bonus.core.supermarket.mapper.SupermarketInfoMapper;
import com.bonus.core.supermarket.mapper.SupermarketMemberMapper;
import com.bonus.core.supermarket.mapper.SupermarketProductMapper;
import com.bonus.core.supermarket.model.SupermarketInfo;
import com.bonus.core.supermarket.po.GoodsBuyLimitModel;
import com.bonus.core.supermarket.po.WarehouseModel;
import com.bonus.core.supermarket.vo.SupermarketProductInfoImageVO;
import com.bonus.core.supermarket.vo.SupermarketQueryProductInfoVO;
import com.bonus.i18n.I18n;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

@Component
public class SupermarketApi {
   private static final Logger log = LoggerFactory.getLogger(SupermarketApi.class);
   @Autowired
   @Lazy
   private SupermarketMemberMapper supermarketMemberMapper;
   @Autowired
   @Lazy
   private SupermarketInfoMapper supermarketInfoMapper;
   @Autowired
   @Lazy
   private SupermarketProductMapper supermarketProductMapper;
//   @Autowired
//   @Lazy
//   private SupermarketConfigMapper supermarketConfigMapper;
   @Autowired
   @Lazy
   private DrpServiceApi drpServiceApi;
   @Autowired
   @Lazy
   private CustInfoApi custInfoApi;
   @Autowired
   @Lazy
   private RedisTemplate<Object, Object> redisTemplate;

   public SupermarketInfo getSupermarketInfoById(Long supermarketId) {
      checkSupermarketId(supermarketId);
      String supermarketRedis = "yst:merchant-id:supermarket:info:supermarket-id"
              .replace("merchant-id", TenantContextHolder.getTenantId().toString())
              .replace("supermarket-id", supermarketId.toString());
      Object cacheObj = RedisUtil.getObj(supermarketRedis);
      if (ObjectUtil.isNotEmpty(cacheObj)) {
         return (SupermarketInfo)cacheObj;
      } else {
         SupermarketInfo supermarketInfo = this.supermarketInfoMapper.selectOne(Wrappers
                 .lambdaQuery(SupermarketInfo.class).eq(SupermarketInfo::getSupermarketId, supermarketId)
                 .eq(SupermarketInfo::getDelFlag, DelFlagEnum.DEL_FALSE.key()));
         RedisUtil.setObj(supermarketRedis, supermarketInfo, 3600L);
         return supermarketInfo;
      }
   }
//
//   public String getSupermarketNameById(Long supermarketId) {
//      checkSupermarketId(supermarketId);
//      SupermarketInfo supermarketInfo = (SupermarketInfo)this.supermarketInfoMapper.selectOne(((LambdaQueryWrapper)((LambdaQueryWrapper)Wrappers.lambdaQuery(SupermarketInfo.class).eq(SupermarketInfo::getSupermarketId, supermarketId)).eq(SupermarketInfo::getDelFlag, DelFlagEnum.DEL_FALSE.key())).select(new SFunction[]{SupermarketInfo::getSupermarketName}));
//      return ObjectUtil.isEmpty(supermarketInfo) ? null : supermarketInfo.getSupermarketName();
//   }

   protected static void checkSupermarketId(Long supermarketId) {
      if (ObjectUtil.isEmpty(supermarketId)) {
         throw new ServiceException(I18n.getMessage("supermarket.id-not-empty", new Object[0]));
      }
   }

   public List<Integer> listMemberPsnType(Long supermarketId) {
      return this.supermarketMemberMapper.listPsnType(supermarketId);
   }

   public WarehouseModel getWarehouseBySupermarketId(Long supermarketId) {
      checkSupermarketId(supermarketId);
      SupermarketInfo supermarketInfo = this.supermarketInfoMapper.selectOne(Wrappers
              .lambdaQuery(SupermarketInfo.class).eq(SupermarketInfo::getSupermarketId, supermarketId)
              .select(SupermarketInfo::getWarehouseId));
      if (ObjectUtil.isEmpty(supermarketInfo)) {
         throw new ServiceException(I18n.getMessage("supermarket.supermarket-not-warehouse"));
      } else {
         String warehouseName = this.drpServiceApi.getWarehouseNameById(supermarketInfo.getWarehouseId());
         return new WarehouseModel(supermarketInfo.getWarehouseId(), warehouseName);
      }
   }

   public boolean ifSupermarketMember(Long custId, Long supermarketId) {
      if (!ObjectUtil.isEmpty(custId) && custId != -1L) {
         List<Integer> psnTypeList = this.listMemberPsnType(supermarketId);
         if (CollUtil.isEmpty(psnTypeList)) {
            return false;
         } else {
            CustInfo custInfo = this.custInfoApi.getCustInfoByCustId(custId);
            if (ObjectUtil.isEmpty(custInfo)) {
               log.info("查无此人!");
               return false;
            } else {
               Integer psnType = custInfo.getPsnType();
               return psnTypeList.contains(psnType);
            }
         }
      } else {
         return false;
      }
   }

   public boolean ifRelateDrp(Long supermarketId) {
      checkSupermarketId(supermarketId);
      SupermarketInfo supermarketInfo = (SupermarketInfo)this.supermarketInfoMapper.selectOne(Wrappers
              .lambdaQuery(SupermarketInfo.class).eq(SupermarketInfo::getSupermarketId, supermarketId)
              .eq(SupermarketInfo::getDelFlag, DelFlagEnum.DEL_FALSE.key())
              .select(SupermarketInfo::getSupermarketId, SupermarketInfo::getIfRelateDrp));
      if (ObjectUtil.isEmpty(supermarketInfo)) {
         throw new ServiceException(I18n.getMessage("supermarket.not-exist", new Object[0]));
      } else {
         return LeConstants.COMMON_YES.equals(supermarketInfo.getIfRelateDrp());
      }
   }

   @Transactional(
      rollbackFor = {Exception.class}
   )
   public void plusSupermarketInventory(List<PlusSupermarketInventoryDetailDTO> detailList) {
      Iterator var2 = detailList.iterator();

      while(var2.hasNext()) {
         PlusSupermarketInventoryDetailDTO detail = (PlusSupermarketInventoryDetailDTO)var2.next();
         this.supermarketProductMapper.plusInventoryByDetailId(detail.getDetailId(), detail.getOperateNum());
      }

   }
//
//   public boolean ifBusiness(Long supermarketId) {
//      int weekDay = LocalDate.now().getDayOfWeek().getValue();
//      BusinessConfigModel businessInfo = this.supermarketConfigMapper.getBusinessInfo(supermarketId, weekDay);
//      if (ObjectUtil.isEmpty(businessInfo)) {
//         throw new LeException(I18n.getMessage("supermarket.config-not-exit", new Object[0]));
//      } else if (businessInfo.getIfBusiness().equals(LeConstants.COMMON_NO)) {
//         return false;
//      } else {
//         LocalTime nowTime = LocalTime.now();
//         return nowTime.isAfter(businessInfo.getOpeningTime()) && nowTime.isBefore(businessInfo.getClosingTime());
//      }
//   }

   public boolean ifAllowRefund(Long supermarketId, LocalDateTime ordTime) {
      LocalDate ordDate = ordTime.toLocalDate();
      if (!ordDate.isEqual(LocalDate.now())) {
         return false;
      } else {
         Integer refundLimitTime = this.supermarketInfoMapper.getRefundLimitTime(supermarketId, AppSaleModeEnum.GOODS_IN_STOCK.key());
         if (ObjectUtil.isEmpty(refundLimitTime)) {
            return false;
         } else {
            LocalDateTime allowRefundTime = ordTime.plusMinutes((long)refundLimitTime);
            LocalDateTime nowTime = LocalDateTime.now();
            return !nowTime.isAfter(allowRefundTime);
         }
      }
   }
//
//   public List<OpenSupermarketListVO> listAllSupermarketInfo(boolean includeDeleted) {
//      List<AppletSupermarketListVO> appletSupermarketListVOList = this.supermarketInfoMapper.listSupermarketInfo(includeDeleted ? DelFlagEnum.DEL_FALSE.key() : null);
//      List<OpenSupermarketListVO> resultList = BeanUtil.copyToList(appletSupermarketListVOList, OpenSupermarketListVO.class);
//      Iterator var4 = resultList.iterator();
//
//      while(var4.hasNext()) {
//         OpenSupermarketListVO supermarketInfoListVO = (OpenSupermarketListVO)var4.next();
//         int todayWeek = LocalDate.now().getDayOfWeek().getValue();
//         SupermarketConfig todayConfig = (SupermarketConfig)this.supermarketConfigMapper.selectOne((Wrapper)((LambdaQueryWrapper)Wrappers.lambdaQuery(SupermarketConfig.class).eq(SupermarketConfig::getWeekType, todayWeek)).eq(SupermarketConfig::getSupermarketId, supermarketInfoListVO.getSupermarketId()));
//         supermarketInfoListVO.setIfBusiness(todayConfig.getIfBusiness());
//         supermarketInfoListVO.setOpeningTime(todayConfig.getOpeningTime());
//         supermarketInfoListVO.setClosingTime(todayConfig.getClosingTime());
//      }
//
//      return resultList;
//   }
//
//   public List<OpenSupermarketProductListVO> listSupermarketProduct(OpenSupermarketProductListDTO content) {
//      boolean ifSupermarketRelateDrp = this.ifRelateDrp(content.getSupermarketId());
//      List<AppletSupermarketProductListVO> appletSupermarketProductListVOList = this.supermarketProductMapper.listProductCategory(content.getSupermarketId(), LeConstants.COMMON_YES, LeConstants.COMMON_YES);
//      List<OpenSupermarketProductListVO> resultList = BeanUtil.copyToList(appletSupermarketProductListVOList, OpenSupermarketProductListVO.class);
//      boolean ifSupermarketMember = this.ifSupermarketMember(content.getCustId(), content.getSupermarketId());
//      Iterator var6 = resultList.iterator();
//
//      while(true) {
//         while(var6.hasNext()) {
//            OpenSupermarketProductListVO result = (OpenSupermarketProductListVO)var6.next();
//            List<AppletSupermarketProductDetailListVO> appletSupermarketProductDetailList = this.supermarketProductMapper.listProductByCategoryId(content.getSupermarketId(), LeConstants.COMMON_YES, LeConstants.COMMON_YES, result.getCategoryId());
//            List<OpenSupermarketProductDetailListVO> productList = BeanUtil.copyToList(appletSupermarketProductDetailList, OpenSupermarketProductDetailListVO.class);
//            if (!ifSupermarketMember) {
//               productList = (List)productList.stream().map((detailx) -> {
//                  detailx.setPrefPrice((Integer)null);
//                  return detailx;
//               }).collect(Collectors.toList());
//            }
//
//            if (!ifSupermarketRelateDrp) {
//               result.setDetailList(productList);
//            } else {
//               Iterator var10 = productList.iterator();
//
//               while(var10.hasNext()) {
//                  OpenSupermarketProductDetailListVO detail = (OpenSupermarketProductDetailListVO)var10.next();
//                  InventoryModel inventoryModel = this.drpServiceApi.getInventoryNumByMaterialId(detail.getMaterialId(), content.getWarehouseId(), detail.getUnitId());
//                  if (ObjectUtil.isEmpty(inventoryModel)) {
//                     detail.setInventoryNum(BigDecimal.ZERO);
//                  } else {
//                     detail.setInventoryId(inventoryModel.getInventoryId());
//                     detail.setInventoryNum(inventoryModel.getInventoryNum());
//                  }
//               }
//            }
//         }
//
//         return resultList;
//      }
//   }
//
//   public List<OpenSupermarketProductPushInfoVO> listProductPushInfo() {
//      return this.supermarketProductMapper.listProductPushInfo();
//   }
//
//   public OpenSupermarketConfigVO getSupermarketConfigById(Long supermarketId) {
//      AppletSupermarketConfigVO appletSupermarketConfigVO = this.supermarketInfoMapper.getConfigById(supermarketId);
//      if (ObjectUtil.isEmpty(appletSupermarketConfigVO)) {
//         throw new LeException(I18n.getMessage("supermarket.not-exist", new Object[0]));
//      } else {
//         OpenSupermarketConfigVO result = (OpenSupermarketConfigVO)LeBeanUtil.copyCreateProperties(appletSupermarketConfigVO, OpenSupermarketConfigVO.class);
//         result.setDeliveryWayList(Arrays.asList(result.getDeliveryWay().split(",")));
//         List<Integer> weekDay = this.supermarketConfigMapper.listReserveWeek(supermarketId, LeConstants.COMMON_YES);
//         LocalDate today = LocalDate.now();
//         Integer todayWeek = today.getDayOfWeek().getValue();
//         List<AppletReserveDayVO> appletReserveDayVOList = new ArrayList();
//         Iterator var8 = weekDay.iterator();
//
//         while(var8.hasNext()) {
//            Integer day = (Integer)var8.next();
//            if (!Objects.equals(todayWeek, day)) {
//               int plusNum;
//               if (todayWeek > day) {
//                  plusNum = 7 - todayWeek + day;
//               } else {
//                  plusNum = day - todayWeek;
//               }
//
//               LocalDate localDate = today.plusDays((long)plusNum);
//               String date = SupermarketUtils.localDateToStrByPattern(localDate, "yyyy-MM-dd");
//               AppletReserveDayVO appletReserveDayVO = new AppletReserveDayVO();
//               appletReserveDayVO.setWeekDay(WeekEnum.getValue(day));
//               appletReserveDayVO.setDate(date);
//               appletReserveDayVOList.add(appletReserveDayVO);
//            }
//         }
//
//         List<AppletReserveDayVO> appletReserveDayVOList = (List)appletReserveDayVOList.stream().sorted(Comparator.comparing(AppletReserveDayVO::getDate)).collect(Collectors.toList());
//         List<OpenReserveDayVO> openReserveDayVOList = BeanUtil.copyToList(appletReserveDayVOList, OpenReserveDayVO.class);
//         result.setReserveDayList(openReserveDayVOList);
//         return result;
//      }
//   }
//
//   public boolean checkIfUseInSupermarket(List<Long> materialIdList) {
//      Integer checkProduct = this.supermarketProductMapper.checkIfUseInSupermarket(materialIdList, DelFlagEnum.DEL_FALSE.key());
//      return checkProduct > 0;
//   }
//
//   public List<SupermarketProduct> listSupermarketProductById(Long materialId) {
//      return this.supermarketProductMapper.selectList((Wrapper)Wrappers.lambdaQuery(SupermarketProduct.class).eq(SupermarketProduct::getMaterialId, materialId));
//   }

   public SupermarketQueryProductInfoVO queryProductInfo(SupermarketQueryProductInfoDTO content) {
      if (!ObjectUtil.isEmpty(content.getGoodsId()) && !ObjectUtil.isEmpty(content.getDetailId())) {
         String supermarketProductRedis = "yst:merchant-id:supermarket:product:productId:detailId"
                 .replace("merchant-id", TenantContextHolder.getTenantId().toString())
                 .replace("productId", content.getGoodsId().toString())
                 .replace("detailId", content.getDetailId().toString());
         Object cacheObj = this.redisTemplate.opsForValue().get(supermarketProductRedis);
         if (ObjectUtil.isNotEmpty(cacheObj)) {
            return (SupermarketQueryProductInfoVO)cacheObj;
         } else {
            SupermarketQueryProductInfoVO result = this.supermarketProductMapper.getProductById(content);
            long random1000 = (long)(Math.random() * 1000.0);
            this.redisTemplate.opsForValue().set(supermarketProductRedis, result, 60000L + random1000, TimeUnit.MILLISECONDS);
            return result;
         }
      } else {
         throw new ServiceException(I18n.getMessage("supermarket.product-id-or-detailId-not-null", new Object[0]));
      }
   }

   public List<SupermarketProductInfoImageVO> getProductImg(List<Long> goodsIdList) {
      return this.supermarketProductMapper.getProductImg(goodsIdList);
   }

//   public List<SupermarketNotRemovedProductListVO> listNotRemovedProduct(SupermarketNotRemovedProductListDTO content) {
//      log.info("[商超]_购物车_获取上架商品_入参:{}", content);
//      if (!ObjectUtil.isEmpty(content.getSupermarketId()) && !CollUtil.isEmpty(content.getMaterialIdList())) {
//         boolean ifRelateDrp = this.ifRelateDrp(content.getSupermarketId());
//         List resultList;
//         if (ifRelateDrp) {
//            resultList = this.supermarketProductMapper.listNotRemovedProduct(content, 1);
//         } else {
//            resultList = this.supermarketProductMapper.listNotRemovedProduct(content, (Integer)null);
//         }
//
//         boolean ifSupermarketMember = this.ifSupermarketMember(content.getCustId(), content.getSupermarketId());
//         if (!ifSupermarketMember) {
//            resultList.forEach((s) -> {
//               s.setPrefPrice((BigDecimal)null);
//            });
//         }
//
//         return resultList;
//      } else {
//         throw new LeException(I18n.getMessage("supermarket.shop-cert-material-not-null", new Object[0]));
//      }
//   }

   public void checkProductLimitBuy(SmtCheckProductLimitBuyDTO content) {
      log.info("[商超]_限购校验_入参：{}", content);
      if (ObjectUtil.isEmpty(content.getSupermarketId())) {
         throw new ServiceException(I18n.getMessage("supermarket.limit-check-supermarket-id-not-exist", new Object[0]));
      } else if (CollUtil.isEmpty(content.getDetailList())) {
         throw new ServiceException(I18n.getMessage("supermarket.limit-check-detail-not-get", new Object[0]));
      } else {
         List<Long> productIdList = content.getDetailList().stream().map(SmtCheckProductLimitBuyDetailDTO::getProductId)
                 .collect(Collectors.toList());
         List<GoodsBuyLimitModel> goodsBuyLimitModelList = this.supermarketProductMapper.listGoodsBuyLimit(content.getSupermarketId(),
                 productIdList, (Integer)null);
         if (CollUtil.isEmpty(goodsBuyLimitModelList)) {
            throw new ServiceException(I18n.getMessage("supermarket.limit-check-supermarket-product-not-exist", new Object[0]));
         } else {
            Map<Long, GoodsBuyLimitModel> goodsBuyLimitMap = goodsBuyLimitModelList.stream().collect(Collectors
                    .toMap(GoodsBuyLimitModel::getMaterialId, Function.identity()));
            Iterator var5 = content.getDetailList().iterator();

            while(var5.hasNext()) {
               SmtCheckProductLimitBuyDetailDTO detail = (SmtCheckProductLimitBuyDetailDTO)var5.next();
               GoodsBuyLimitModel goodsBuyLimitModel = (GoodsBuyLimitModel)goodsBuyLimitMap.get(detail.getProductId());
               if (!ObjectUtil.isEmpty(goodsBuyLimitModel)) {
                  if (detail.getCurrentProductNum() > goodsBuyLimitModel.getPersonLimit()) {
                     throw new ServiceException(I18n.getMessage("supermarket.limit-check-over-each-order-limit",
                             new Object[]{detail.getProductName()}));
                  }

                  if (detail.getCurrentProductNum() + detail.getTodayProductNum() > goodsBuyLimitModel.getOneDayLimit()) {
                     throw new ServiceException(I18n.getMessage("supermarket.limit-check-over-each-day-limit",
                             new Object[]{detail.getProductName()}));
                  }
               }
            }
         }
      }
   }

   public Long getAreaIdBySupermarketId(Long supermarketId) {
      checkSupermarketId(supermarketId);
      SupermarketInfo supermarketInfo = (SupermarketInfo)this.supermarketInfoMapper.selectOne(Wrappers
              .lambdaQuery(SupermarketInfo.class).eq(SupermarketInfo::getSupermarketId, supermarketId)
              .select(SupermarketInfo::getSupermarketId, SupermarketInfo::getAreaId));
      if (ObjectUtil.isEmpty(supermarketInfo)) {
         throw new ServiceException(I18n.getMessage("supermarket.not-exist", new Object[0]));
      } else {
         return supermarketInfo.getAreaId();
      }
   }
}
