package com.bonus.canteen.core.nutrition.common.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
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.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bonus.canteen.core.allocation.api.AllocMealtimeApi;
import com.bonus.canteen.core.customer.constants.CustAgeEnum;
import com.bonus.canteen.core.nutrition.common.dto.HealthCateringDetailQueryDTO;
import com.bonus.canteen.core.nutrition.common.dto.HealthCateringEditDTO;
import com.bonus.canteen.core.nutrition.common.dto.HealthRecipeDayAddDTO;
import com.bonus.canteen.core.nutrition.common.enums.PregnantStatusEnum;
import com.bonus.canteen.core.nutrition.common.mapper.HealthCateringMapper;
import com.bonus.canteen.core.nutrition.common.mapper.NutrReferenceIntakeMapper;
import com.bonus.canteen.core.nutrition.common.model.HealthCatering;
import com.bonus.canteen.core.nutrition.common.model.NutrientReferenceIntake;
import com.bonus.canteen.core.nutrition.common.service.HealthCateringService;
import com.bonus.canteen.core.nutrition.common.service.HealthInfoService;
import com.bonus.canteen.core.nutrition.common.service.NutrientReferenceIntakeReviseService;
import com.bonus.canteen.core.nutrition.common.vo.*;
import com.bonus.canteen.core.nutrition.constant.NutritionConstants;
import com.bonus.canteen.core.nutrition.constant.YesOrNoEnum;
import com.bonus.canteen.core.nutrition.utils.NuConvertUtil;
import com.bonus.common.houqin.i18n.I18n;
import com.bonus.common.houqin.utils.LeBeanUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.invoke.SerializedLambda;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Service
public class HealthCateringServiceImpl extends ServiceImpl<HealthCateringMapper, HealthCatering> implements HealthCateringService {
//   @Autowired
//   @Lazy
//   private AllocMealtimeApi allocMealtimeApi;
//   @Autowired
//   @Lazy
//   private HealthRecipeService healthRecipeService;
   @Autowired
   @Lazy
   private HealthInfoService healthInfoService;
   @Autowired
   @Lazy
   private NutrientReferenceIntakeReviseService nutrientReferenceIntakeReviseService;
   @Resource
   private NutrReferenceIntakeMapper nutrReferenceIntakeMapper;
//   @Resource
//   private HealthCateringMapper healthCateringMapper;
//   @Resource
//   private HealthCateringDetailMapper healthCateringDetailMapper;
//   @Resource
//   private HealthRecipeDishesMapper healthRecipeDishesMapper;

   public NutrReferenceIntakeVO getCustIntake(Long custId) {
      Integer defaultAge = NutritionConstants.DEFAULT_AGE;
      Integer defaultSex = NutritionConstants.DEFAULT_SEX;
      Integer defaultLabourIntensity = NutritionConstants.DEFAULT_LABOUR_INTENSITY;
      Boolean ifPregnancyRelated = false;
      Integer pregnantStatus = 0;
      if (ObjectUtil.isNotNull(custId)) {
         HealthInfoSimpleVo healthInfo = this.healthInfoService.simplifyHealthInfo(custId);
         if (ObjectUtils.isNotNull(healthInfo)) {
            defaultAge = ObjectUtils.isNotNull(healthInfo.getBirthday()) ? CustAgeEnum.getAge(healthInfo.getBirthday()) : (ObjectUtils.isNotNull(new Object[]{healthInfo.getAge()}) ? healthInfo.getAge() : defaultAge);
            defaultSex = !ObjectUtils.isNull(healthInfo.getSex()) && !NumberUtil.equals(healthInfo.getSex(), NutritionConstants.SEX_NON) ? healthInfo.getSex() : defaultSex;
            defaultLabourIntensity = ObjectUtils.isNotNull(healthInfo.getLabourIntensity()) ? healthInfo.getLabourIntensity() : defaultLabourIntensity;
            pregnantStatus = (Integer)Optional.ofNullable(healthInfo.getPregnantStatus()).orElse(PregnantStatusEnum.SECRET.key());
            ifPregnancyRelated = CollUtil.contains(CollUtil.newArrayList(PregnantStatusEnum.FIRST_TRIMESTER.key(), PregnantStatusEnum.SECOND_TRIMESTER.key(), PregnantStatusEnum.LATE_PREGNANCY.key(), PregnantStatusEnum.WET_NURSE.key()), pregnantStatus);
         }
      }

      NutrientReferenceIntake nutrientReferenceIntake = this.nutrReferenceIntakeMapper.selectOne(((Wrappers.lambdaQuery(NutrientReferenceIntake.class).eq(NutrientReferenceIntake::getCustAge, defaultAge)).eq(NutrientReferenceIntake::getCustSex, defaultSex)).eq(NutrientReferenceIntake::getActivityLevel, defaultLabourIntensity));
      if (ObjectUtils.isNotEmpty(nutrientReferenceIntake) && NumberUtil.equals(nutrientReferenceIntake.getFat(), BigDecimal.ZERO)) {
         nutrientReferenceIntake.setFat(nutrientReferenceIntake.getCalories().multiply(NutritionConstants.STANDARD_VAL1).divide(NutritionConstants.STANDARD_VAL3, NutritionConstants.NEW_SCALE, RoundingMode.HALF_UP));
      }

      NutrReferenceIntakeVO referenceIntakeVO = ObjectUtil.isNull(nutrientReferenceIntake) ? new NutrReferenceIntakeVO() : (NutrReferenceIntakeVO) LeBeanUtil.copyCreateProperties(nutrientReferenceIntake, NutrReferenceIntakeVO.class);
      if (ifPregnancyRelated) {
         NutrReferenceIntakeVO nutrReferenceIntakeVO = this.nutrientReferenceIntakeReviseService.getInfoByPregnantStatus(pregnantStatus);
         referenceIntakeVO = NuConvertUtil.sumDoubleValues(CollUtil.newArrayList(referenceIntakeVO, nutrReferenceIntakeVO));
      }

      if (ObjectUtil.isNull(referenceIntakeVO.getCalcium()) && ObjectUtil.isNull(referenceIntakeVO.getPhosphorus())) {
         referenceIntakeVO.setDietaryFiber(null).setCholesterol(null);
      }

      return referenceIntakeVO;
   }

//   public List<HealthCateringVO> listCateringDetail(HealthCateringDetailQueryDTO content) {
//      List<HealthCateringVO> healthCaterings = CollUtil.newArrayList(new HealthCateringVO[0]);
//      content.setIfVisible(YesOrNoEnum.YES.key());
//
//      for(int i = 1; i <= 7; ++i) {
//         Long custId = content.getCustId();
//         content.setDetailDay(i);
//         HealthCateringVO healthCatering = (HealthCateringVO)Optional.ofNullable(((HealthCateringMapper)this.baseMapper).getCateringBaseInfo(content)).orElse(new HealthCateringVO());
//         healthCatering.setDetailDay(i);
//         List<HealthRecipeDetailVO> recipeDetailVOS = this.healthCateringDetailMapper.listCateringDetailForDay(content);
//         healthCatering.setHealthRecipeDetailVOList(recipeDetailVOS);
//         List<HealthNutritionVO> healthNutritionVOS = this.healthRecipeService.buildNutritionAndRawMaterial(recipeDetailVOS, custId);
//         healthCatering.setHealthNutritionVOS(healthNutritionVOS);
//         Map<Integer, String> mealtimeMap = this.allocMealtimeApi.getMealtimeNameMap();
//         recipeDetailVOS.forEach((healthRecipeDetailVO) -> {
//            healthRecipeDetailVO.setMealtimeName((String)mealtimeMap.get(healthRecipeDetailVO.getMealtimeType()));
//         });
//         healthCaterings.add(healthCatering);
//      }
//
//      return healthCaterings;
//   }
//
//   @Transactional(
//      rollbackFor = {Exception.class}
//   )
//   public void editCatering(HealthCateringEditDTO healthCateringEditDTO) {
//      HealthCatering healthCatering = (HealthCatering)this.healthCateringMapper.selectOne((Wrapper)((LambdaQueryWrapper)Wrappers.lambdaQuery(HealthCatering.class).eq(HealthCatering::getCustId, healthCateringEditDTO.getCustId())).eq(HealthCatering::getDelFlag, DelFlagEnum.DEL_FALSE.key()));
//      if (ObjectUtils.isEmpty(healthCatering)) {
//         healthCatering = (HealthCatering)LeBeanUtil.copyCreateProperties(healthCateringEditDTO, HealthCatering.class);
//         healthCatering.setHealthCateringId(Id.next());
//         this.healthCateringMapper.insert(healthCatering);
//      } else {
//         Long healthCateringId = healthCateringEditDTO.getHealthCateringId();
//         if (ObjectUtils.isNull(new Object[]{healthCateringId})) {
//            throw new LeException(I18n.getMessage("nutrition.recipe.recipeId.nonNull", new Object[0]));
//         }
//
//         this.healthCateringMapper.update((HealthCatering)LeBeanUtil.copyCreateProperties(healthCateringEditDTO, HealthCatering.class), (Wrapper)Wrappers.lambdaUpdate(HealthCatering.class).eq(HealthCatering::getHealthCateringId, healthCateringId));
//         List<Long> detailIdList = this.healthCateringDetailMapper.selectCateringDetailIdList(healthCateringEditDTO.getCustId());
//         this.healthCateringDetailMapper.delete((Wrapper)Wrappers.lambdaQuery(HealthCateringDetail.class).eq(HealthCateringDetail::getCustId, healthCateringEditDTO.getCustId()));
//         if (CollUtil.isNotEmpty(detailIdList)) {
//            this.healthRecipeDishesMapper.delete((Wrapper)((LambdaQueryWrapper)Wrappers.lambdaQuery(HealthRecipeDishes.class).in(HealthRecipeDishes::getHealthDetailId, detailIdList)).eq(HealthRecipeDishes::getDishesType, 2));
//         }
//      }
//
//      List<HealthRecipeDayAddDTO> healthCateringDayDTOList = healthCateringEditDTO.getHealthCateringDayDTOList();
//      if (CollUtil.isNotEmpty(healthCateringDayDTOList)) {
//         healthCateringDayDTOList.forEach((daily) -> {
//            daily.getHealthRecipeDetailAddDTOS().forEach((meal) -> {
//               HealthCateringDetail healthCateringDetail = new HealthCateringDetail();
//               healthCateringDetail.setHealthDetailId(Id.next());
//               healthCateringDetail.setCustId(healthCateringEditDTO.getCustId());
//               healthCateringDetail.setDetailDay(daily.getDetailDay());
//               healthCateringDetail.setMealtimeType(meal.getMealtimeType());
//               this.healthCateringDetailMapper.insert(healthCateringDetail);
//               meal.getDishesList().forEach((dish) -> {
//                  HealthRecipeDishes healthRecipeDishes = (HealthRecipeDishes)LeBeanUtil.copyCreateProperties(dish, HealthRecipeDishes.class);
//                  healthRecipeDishes.setHealthDetailId(healthCateringDetail.getHealthDetailId());
//                  healthRecipeDishes.setDishesType(2);
//                  this.healthRecipeDishesMapper.insert(healthRecipeDishes);
//               });
//            });
//         });
//      }
//
//   }
//
//   public void delCatering(Long custId) {
//      this.healthCateringMapper.update((Object)null, (Wrapper)((LambdaUpdateWrapper)Wrappers.lambdaUpdate(HealthCatering.class).eq(HealthCatering::getCustId, custId)).set(HealthCatering::getDelFlag, DelFlagEnum.DEL_TRUE.key()));
//      List<Long> detailIdList = this.healthCateringDetailMapper.selectCateringDetailIdList(custId);
//      if (CollectionUtil.isNotEmpty(detailIdList)) {
//         this.healthCateringDetailMapper.delete((Wrapper)Wrappers.lambdaQuery(HealthCateringDetail.class).in(HealthCateringDetail::getHealthDetailId, detailIdList));
//         this.healthRecipeDishesMapper.delete((Wrapper)Wrappers.lambdaQuery(HealthRecipeDishes.class).in(HealthRecipeDishes::getHealthDetailId, detailIdList));
//      }
//
//   }
//
//   public NutrReferenceIntakeVO getReferenceIntake(CustInfoIntakeDTO custInfoIntakeDTO) {
//      NutrientReferenceIntake nutrientReferenceIntake = (NutrientReferenceIntake)this.nutrReferenceIntakeMapper.selectOne((Wrapper)((LambdaQueryWrapper)((LambdaQueryWrapper)Wrappers.lambdaQuery(NutrientReferenceIntake.class).eq(NutrientReferenceIntake::getCustAge, custInfoIntakeDTO.getAge())).eq(NutrientReferenceIntake::getCustSex, custInfoIntakeDTO.getSex())).eq(NutrientReferenceIntake::getActivityLevel, custInfoIntakeDTO.getLabourIntensity()));
//      NutrReferenceIntakeVO referenceIntakeVO = new NutrReferenceIntakeVO();
//      if (ObjectUtils.isNotEmpty(nutrientReferenceIntake)) {
//         referenceIntakeVO = (NutrReferenceIntakeVO)LeBeanUtil.copyCreateProperties(nutrientReferenceIntake, NutrReferenceIntakeVO.class);
//      }
//
//      return referenceIntakeVO;
//   }
}
