package com.bonus.canteen.core.marketing.v2.constants;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.bonus.canteen.core.allocation.holiday.constants.HolidayTypeEnum;
import com.bonus.canteen.core.allocation.holiday.model.MktHoliday;
import com.bonus.canteen.core.allocation.holiday.service.MktHolidayService;
import com.bonus.canteen.core.common.utils.SpringContextHolder;
import com.bonus.canteen.core.marketing.util.EnumUtil;
import com.bonus.canteen.core.marketing.util.ICommonEnum;
import com.bonus.canteen.core.marketing.vo.MarketRuleVO;

import java.time.LocalDate;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public enum MarketEffectPeriodEnum implements ICommonEnum {
   PERIOD_EVERYDAY(1, "每天") {
      public boolean exec(MarketRuleVO ruleInfo, LocalDate consumeDate) {
         return true;
      }
   },
   PERIOD_WEEK(2, "每周") {
      @Override
      public boolean exec(MarketRuleVO ruleInfo, LocalDate consumeDate) {
         int day = LocalDateTimeUtil.dayOfWeek(consumeDate).getIso8601Value();
         return CollUtil.contains(ruleInfo.getEffectPeriodValue(), day);
      }
   },
   PERIOD_MONTH(3, "每月") {
      @Override
      public boolean exec(MarketRuleVO ruleInfo, LocalDate consumeDate) {
         int day = consumeDate.getDayOfMonth();
         return CollUtil.contains(ruleInfo.getEffectPeriodValue(), day);
      }
   },
   PERIOD_TYPE(4, "日期类型") {
      private final MktHolidayService holidayService = (MktHolidayService) SpringContextHolder.getBean(MktHolidayService.class);

      @Override
      public boolean exec(MarketRuleVO ruleInfo, LocalDate consumeDate) {
         List<MktHoliday> mktHolidays = this.holidayService.listHolidayByDate(consumeDate);
         List<Integer> holidayTypes = (List)mktHolidays.stream().map(MktHoliday::getHolType).collect(Collectors.toList());
         if (CollUtil.isEmpty(holidayTypes)) {
            holidayTypes.add(HolidayTypeEnum.WORK_DAY.key());
         }

         return CollUtil.containsAny(ruleInfo.getEffectPeriodValue(), holidayTypes);
      }
   };

   private final Integer key;
   private final String value;

   public abstract boolean exec(MarketRuleVO ruleInfo, LocalDate consumeDate);

   public static boolean operate(MarketRuleVO ruleInfo, LocalDate consumeDate) {
      MarketEffectPeriodEnum periodEnum = (MarketEffectPeriodEnum) EnumUtil.getEnumByKey(MarketEffectPeriodEnum.class, ruleInfo.getEffectPeriod());
      return !Objects.isNull(periodEnum) && periodEnum.exec(ruleInfo, consumeDate);
   }

   @Override
   public Integer getKey() {
      return this.key;
   }

   @Override
   public String getValue() {
      return this.value;
   }

   private MarketEffectPeriodEnum(final Integer key, final String value) {
      this.key = key;
      this.value = value;
   }

   // $FF: synthetic method
   private static MarketEffectPeriodEnum[] $values() {
      return new MarketEffectPeriodEnum[]{PERIOD_EVERYDAY, PERIOD_WEEK, PERIOD_MONTH, PERIOD_TYPE};
   }
}
