package com.bonus.core.allocation.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.constant.LeConstants;
import com.bonus.core.allocation.alloc.model.AllocMetadata;
import com.bonus.core.allocation.alloc.service.AllocMetadataService;
import com.bonus.core.common.enums.AllocMealtimeTypeEnum;
import com.bonus.core.common.enums.MetadataModelTypeEnum;
import com.bonus.core.common.redis.RedisUtil;
import com.bonus.core.common.utils.JacksonUtil;
import com.bonus.core.menu.model.AllocMealtimeMenuModel;
import com.bonus.core.menu.model.AllocMealtimeModel;
import com.bonus.core.menu.model.AllocMealtimeStateModel;
import com.bonus.core.order.utils.LeNumUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.time.LocalTime;
import java.util.*;

@Component
public class AllocMealtimeApi {
   private static final Logger log = LoggerFactory.getLogger(AllocMealtimeApi.class);
   @Autowired
   @Lazy
   private GlobalMetadataApi globalMetadataApi;
   @Autowired
   @Lazy
   private AllocMetadataService allocMetadataService;
   @Autowired
   @Lazy
   private AllocStallApi allocStallApi;

   public List<AllocMealtimeModel> listUseAvailableMealtime(Long canteenId, Long stallId, Integer ifUse) {
      List<AllocMealtimeModel> mealtimeModelList = this.listAvailableMealtime(canteenId, stallId);
      if (LeConstants.COMMON_YES.equals(ifUse)) {
         mealtimeModelList.removeIf((mealtimeModel) -> {
            return LeConstants.COMMON_NO.equals(mealtimeModel.getIfUse());
         });
      }

      return mealtimeModelList;
   }

   public AllocMealtimeMenuModel getAllocMealtimeMenuModel(Long stallId) {
      List<AllocMealtimeModel> mealtimeModelList = this.listUseAvailableMealtime((Long)null, stallId, (Integer)null);
      String ifAllowReserveToday = this.globalMetadataApi.getAvailableValue(MetadataModelTypeEnum.ORDER_RESERVE, "ifAllowReserveToday", (Long)null, stallId);
      AllocMealtimeMenuModel mealtimeMenuModel = new AllocMealtimeMenuModel(ifAllowReserveToday);
      List<AllocMealtimeStateModel> stateModelList = new ArrayList();
      Iterator var6 = mealtimeModelList.iterator();

      while(var6.hasNext()) {
         AllocMealtimeModel mealtimeModel = (AllocMealtimeModel)var6.next();
         AllocMealtimeStateModel stateModel = new AllocMealtimeStateModel(mealtimeModel);
         stateModelList.add(stateModel);
      }

      mealtimeMenuModel.setMealtimeStateModelList(stateModelList);
      return mealtimeMenuModel;
   }

   public Map<Integer, String> getMealtimeNameMap() {
      Map<Integer, String> mealtimeMap = new HashMap();
      AllocMealtimeTypeEnum[] var2 = AllocMealtimeTypeEnum.values();
      int var3 = var2.length;

      for(int var4 = 0; var4 < var3; ++var4) {
         AllocMealtimeTypeEnum mealtimeTypeEnum = var2[var4];
         mealtimeMap.put(mealtimeTypeEnum.getKey(), mealtimeTypeEnum.getDesc());
      }

      return mealtimeMap;
   }

   public List<LocalTime> getStartMealtimeList(Integer addMinutes) {
      List<AllocMealtimeModel> mealtimeModelList = this.listUseAvailableMealtime((Long)null, (Long)null, LeConstants.COMMON_YES);
      if (CollUtil.isEmpty(mealtimeModelList)) {
         return new ArrayList();
      } else {
         List<LocalTime> startMealtimeList = new ArrayList();
         Iterator var4 = mealtimeModelList.iterator();

         while(var4.hasNext()) {
            AllocMealtimeModel mealtimeModel = (AllocMealtimeModel)var4.next();
            startMealtimeList.add(mealtimeModel.getStartTime().plusMinutes((long)addMinutes));
         }

         return startMealtimeList;
      }
   }

   public List<LocalTime> getEndMealtimeList() {
      List<AllocMealtimeModel> mealtimeModelList = this.listUseAvailableMealtime((Long)null, (Long)null, LeConstants.COMMON_YES);
      if (CollUtil.isEmpty(mealtimeModelList)) {
         return new ArrayList();
      } else {
         List<LocalTime> endMealtimeList = new ArrayList();
         Iterator var3 = mealtimeModelList.iterator();

         while(var3.hasNext()) {
            AllocMealtimeModel mealtimeModel = (AllocMealtimeModel)var3.next();
            endMealtimeList.add(mealtimeModel.getEndTime());
         }

         return endMealtimeList;
      }
   }

   private List<AllocMealtimeModel> listAvailableMealtime(Long canteenId, Long stallId) {
      String var10000 = this.allocMetadataService.getCacheKeyPrefix();
      String key = var10000 + "mealtime-canteen-stall:" + String.valueOf(LeNumUtil.isValidId(canteenId) ? canteenId : "-1") + "_" + String.valueOf(LeNumUtil.isValidId(stallId) ? stallId : "-1");
      String cacheStr = RedisUtil.getString(key);
      List cacheObj;
      if (CharSequenceUtil.isNotBlank(cacheStr)) {
         cacheObj = (List)JacksonUtil.readValue(cacheStr, List.class, AllocMealtimeModel.class);
         if (cacheObj != null) {
            return cacheObj;
         }
      }

      cacheObj = this.globalMetadataApi.getAvailableList(MetadataModelTypeEnum.MEALTIME, canteenId, stallId);
      List<AllocMealtimeModel> mealtimeList = new ArrayList();
      Iterator var7 = cacheObj.iterator();

      while(var7.hasNext()) {
         AllocMetadata metadata = (AllocMetadata)var7.next();
         if (CharSequenceUtil.isNotBlank(metadata.getModelValue()) && metadata.getModelValue().contains("{")) {
            AllocMealtimeModel mealtimeModel = (AllocMealtimeModel)JSONObject.parseObject(metadata.getModelValue(), AllocMealtimeModel.class);
            mealtimeModel.setCanteenId(metadata.getCanteenId());
            mealtimeModel.setStallId(metadata.getStallId());
            mealtimeList.add(mealtimeModel);
         }
      }

      RedisUtil.setString(key, JacksonUtil.writeValueAsString(mealtimeList), 1800L);
      return mealtimeList;
   }

   public AllocMealtimeModel getUseAssignTimeMealtime(LocalTime assignTime, Long canteenId, Long stallId) {
      if (ObjectUtil.isNotNull(stallId) && stallId.equals(0L)) {
         stallId = null;
      }

      List<AllocMealtimeModel> mealtimeList = this.listUseAvailableMealtime(canteenId, stallId, LeConstants.COMMON_YES);
      Iterator var5 = mealtimeList.iterator();

      AllocMealtimeModel mealtime;
      do {
         if (!var5.hasNext()) {
            return null;
         }

         mealtime = (AllocMealtimeModel)var5.next();
      } while(assignTime.compareTo(mealtime.getStartTime()) < 0 || assignTime.compareTo(mealtime.getEndTime()) > 0);

      return mealtime;
   }

   public AllocMealtimeModel getAvailableMealtimeByType(Integer mealtimeType, Long canteenId, Long stallId) {
      List<AllocMealtimeModel> mealtimeList = this.listUseAvailableMealtime(canteenId, stallId, LeConstants.COMMON_YES);
      Iterator var5 = mealtimeList.iterator();

      AllocMealtimeModel mealtimeModel;
      do {
         if (!var5.hasNext()) {
            return null;
         }

         mealtimeModel = (AllocMealtimeModel)var5.next();
      } while(!mealtimeType.equals(mealtimeModel.getMealtimeType()));

      return mealtimeModel;
   }

   public AllocMealtimeModel getAndCheckNowMealtime(Long canteenId, Long stallId) {
      List<AllocMealtimeModel> mealtimeList = this.listUseAvailableMealtime(canteenId, stallId, LeConstants.COMMON_YES);
      LocalTime assignTime = LocalTime.now();
      Iterator var5 = mealtimeList.iterator();

      AllocMealtimeModel mealtime;
      do {
         if (!var5.hasNext()) {
            throw new ServiceException("当前时间,不在就餐时间段");
         }

         mealtime = (AllocMealtimeModel)var5.next();
      } while(assignTime.compareTo(mealtime.getStartTime()) < 0 || assignTime.compareTo(mealtime.getEndTime()) > 0);

      return mealtime;
   }
}
