package com.bonus.canteen.core.allocation.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.bonus.canteen.core.allocation.canteen.mapper.AllocStallMapper;
import com.bonus.common.houqin.constant.LeConstants;
import com.bonus.canteen.core.allocation.alloc.model.AllocMetadata;
import com.bonus.canteen.core.allocation.alloc.service.AllocMetadataService;
import com.bonus.canteen.core.allocation.canteen.model.AllocStall;
import com.bonus.canteen.core.allocation.util.MetadataUtil;
import com.bonus.canteen.core.common.enums.MetadataModelTypeEnum;
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 javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Component
public class GlobalMetadataApi {
   private static final Logger log = LoggerFactory.getLogger(GlobalMetadataApi.class);
   @Resource
   @Lazy
   private AllocMetadataService allocMetadataService;

   @Resource
   private AllocStallMapper allocStallMapper;

   @Resource
   @Lazy
   private AllocStallApi allocStallApi;

   public <T> T getModel(MetadataModelTypeEnum modelTypeEnum, T t, Long canteenId, Long stallId) {
      List<AllocMetadata> metadataList = this.getList(modelTypeEnum, canteenId, stallId);
      return MetadataUtil.transferToPayModel(metadataList, t);
   }

   public List<AllocMetadata> getList(MetadataModelTypeEnum modelTypeEnum, Long canteenId, Long stallId) {
      Long finalCanteenId = ObjectUtil.equal(canteenId, -1) ? null : canteenId;
      Long finalStallId = ObjectUtil.equal(stallId, -1) ? null : stallId;
      return this.allocMetadataService.listPayMetadataByType(modelTypeEnum, finalCanteenId, finalStallId);
   }

   public String getAvailableValue(MetadataModelTypeEnum modelTypeEnum, String modelKey, Long canteenId, Long stallId) {
      return this.getAvailableValue(modelTypeEnum, modelKey, "", canteenId, stallId);
   }

   public String getAvailableValue(MetadataModelTypeEnum modelTypeEnum, String modelKey, String defaultValue, Long canteenId, Long stallId) {
      List<AllocMetadata> metadataList = this.getAvailableList(modelTypeEnum, canteenId, stallId);
      return (String)metadataList.stream().filter((s) -> {
         return StrUtil.equals(s.getModelKey(), modelKey);
      }).map(AllocMetadata::getModelValue).filter(Objects::nonNull).findFirst().orElse(defaultValue);
   }

   public List<AllocMetadata> getAvailableList(MetadataModelTypeEnum modelTypeEnum, Long canteenId, Long stallId) {
      if (ObjectUtil.isNotNull(stallId) && ObjectUtil.isNull(canteenId)) {
         AllocStall stall = this.allocStallApi.getAllocStall(stallId);
         if (!ObjectUtil.isNull(stall) && !ObjectUtil.isNull(stall.getCanteenId())) {
            canteenId = stall.getCanteenId();
         } else {
            log.warn("【配置项】未查到档口关联食堂：{},{},{}", new Object[]{modelTypeEnum, canteenId, stallId});
         }
      }

      Long finalCanteenId = ObjectUtil.equal(canteenId, -1) ? null : canteenId;
      Long finalStallId = ObjectUtil.equal(stallId, -1) ? null : stallId;
      if (!modelTypeEnum.supportSeparated() || finalCanteenId == null && finalStallId == null) {
         log.info("[配置]查询返回商户层配置信息");
         return this.allocMetadataService.listPayMetadataByType(modelTypeEnum, finalCanteenId, finalStallId);
      } else {
         List<AllocMetadata> metadataList = (List)this.allocMetadataService.listPayMetadataCacheable(modelTypeEnum).stream().filter((s) -> {
            return LeConstants.COMMON_YES.equals(s.getIfActive());
         }).collect(Collectors.toList());
         List<AllocMetadata> stallList = CollUtil.newArrayList(new AllocMetadata[0]);
         List<AllocMetadata> canteenList = CollUtil.newArrayList(new AllocMetadata[0]);
         List<AllocMetadata> merchantList = CollUtil.newArrayList(new AllocMetadata[0]);
         Iterator var11 = metadataList.iterator();

         while(var11.hasNext()) {
            AllocMetadata metadata = (AllocMetadata)var11.next();
            if (metadata.getStallId() != null) {
               stallList.add(metadata);
            } else if (metadata.getCanteenId() != null) {
               canteenList.add(metadata);
            } else {
               merchantList.add(metadata);
            }
         }

         List result;
         if (finalStallId != null && CollUtil.isNotEmpty(stallList)) {
            log.warn("[配置]返回档口层配置信息,canteenId:{}, stallId:{}", canteenId, stallId);
            result = (List)stallList.stream().filter((s) -> {
               return ObjectUtil.equal(s.getStallId(), finalStallId);
            }).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(result)) {
               return result;
            }
         }

         if (finalCanteenId != null) {
            log.warn("[配置]返回食堂层配置信息,canteenId:{}, stallId:{}", canteenId, stallId);
            result = (List)canteenList.stream().filter((s) -> {
               return ObjectUtil.equal(s.getCanteenId(), finalCanteenId);
            }).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(result)) {
               return result;
            }
         }

         log.warn("[配置]返回商户层配置信息,canteenId:{}, stallId:{}", canteenId, stallId);
         return merchantList;
      }
   }

   public <T> T getAvailableModel(MetadataModelTypeEnum modelTypeEnum, T t, Long canteenId, Long stallId) {
      List<AllocMetadata> metadataList =new ArrayList<>();
      if("order".equals(modelTypeEnum.getKey())){
         metadataList=allocStallMapper.queryAvailableOrder(modelTypeEnum.getKey(),canteenId,stallId);
      }else{
         metadataList = this.getAvailableList(modelTypeEnum, canteenId, stallId);
      }
      return MetadataUtil.transferToPayModel(metadataList, t);
   }

   public void saveValue(MetadataModelTypeEnum modelTypeEnum, String modelKey, String modelValue, Long canteenId, Long stallId) {
      AllocMetadata allocMetadata = new AllocMetadata();
      allocMetadata.setModelType(modelTypeEnum.getKey());
      allocMetadata.setModelKey(modelKey);
      allocMetadata.setModelValue(modelValue);
      allocMetadata.setCanteenId(canteenId);
      allocMetadata.setStallId(stallId);
      this.saveList(CollUtil.toList(new AllocMetadata[]{allocMetadata}));
   }
   public void saveList(List<AllocMetadata> payMetadataList) {
      this.allocMetadataService.savePayMetadata(payMetadataList);
   }

   public <T> T getModelByAreaId(MetadataModelTypeEnum modelTypeEnum, T t, Long areaId) {
      List<AllocMetadata> metadataList = this.allocMetadataService.listPayMetadataByTypeAreaId(modelTypeEnum, areaId);
      return MetadataUtil.transferToPayModel(metadataList, t);
   }
}
