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

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.bonus.canteen.core.account.v4.api.CardInfoServiceV4Api;
import com.bonus.canteen.core.common.constant.NuclearModeEnum;
import com.bonus.canteen.core.common.page.PageVO;
import com.bonus.canteen.core.customer.api.CustInfoApi;
import com.bonus.canteen.core.customer.model.CustInfo;
import com.bonus.canteen.core.menu.constant.NutritionConstants;
import com.bonus.canteen.core.nutrition.common.dto.HealthMonitoringPageDTO;
import com.bonus.canteen.core.nutrition.common.model.HealthBodyRecord;
import com.bonus.canteen.core.nutrition.common.service.HealthBodyRecordService;
import com.bonus.canteen.core.nutrition.common.service.HealthCateringService;
import com.bonus.canteen.core.nutrition.common.service.HealthDishesNutritionService;
import com.bonus.canteen.core.nutrition.common.service.HealthInfoService;
import com.bonus.canteen.core.nutrition.common.vo.HealthBodyRecordPageVO;
import com.bonus.canteen.core.nutrition.common.vo.HealthInfoSimpleVo;
import com.bonus.canteen.core.nutrition.common.vo.HealthNormalElementsVo;
import com.bonus.canteen.core.nutrition.common.vo.NutrReferenceIntakeVO;
import com.bonus.canteen.core.nutrition.device.dto.PersonalNutritionAnalyseDTO;
import com.bonus.canteen.core.nutrition.device.vo.PersonalNutritionAnalyseVO;
import com.bonus.canteen.core.nutrition.utils.NuConvertUtil;
import com.bonus.canteen.core.order.deprecated.dto.OrdLeCodeDTO;
import com.bonus.common.core.exception.ServiceException;
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 java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class NutritionDeviceApi {
   @Autowired
   @Lazy
   private HealthInfoService healthInfoService;
   @Autowired
   @Lazy
   private HealthBodyRecordService healthBodyRecordService;
//   @Autowired
//   @Lazy
//   private HealthChronicService healthChronicService;
   @Autowired
   @Lazy
   private HealthCateringService healthCateringService;
   @Autowired
   @Lazy
   private HealthDishesNutritionService healthDishesNutritionService;
   @Autowired
   @Lazy
   private CardInfoServiceV4Api cardInfoServiceV4Api;
   @Autowired
   @Lazy
   private CustInfoApi custInfoApi;

//   public HealthInfoSimpleVo updateCustHealthInfo(UpdateCustHealthInfoDTO updateCustHealthInfoDTO) {
//      if (NuclearModeEnum.NUCLEAR_MODE_CREDIT.getKey().equals(updateCustHealthInfoDTO.getNuClearMode())) {
//         updateCustHealthInfoDTO.setCustId(this.cardInfoServiceV4Api.queryCustIdBySerialNum(updateCustHealthInfoDTO.getSerialNum()));
//      }
//
//      if (NuclearModeEnum.NUCLEAR_MODE_QRCODE.getKey().equals(updateCustHealthInfoDTO.getNuClearMode())) {
//         String leniucode = updateCustHealthInfoDTO.getAuthCode().substring(4);
//         OrdLeCodeDTO ordLeCodeDto = (OrdLeCodeDTO)JSON.parseObject(leniucode, OrdLeCodeDTO.class);
//         updateCustHealthInfoDTO.setCustId(ordLeCodeDto.getP());
//      }
//
//      HealthInfoSimpleVo healthInfoSimpleVo = this.healthInfoService.simplifyHealthInfo(updateCustHealthInfoDTO.getCustId());
//      if (Objects.isNull(healthInfoSimpleVo)) {
//         throw new LeException(RetCodeEnum.PAY_PERSONAL_NO_EXIT, RetCodeEnum.PAY_PERSONAL_NO_EXIT.getDesc());
//      } else {
//         HealthBodyRecord healthBodyRecord = (HealthBodyRecord) LeBeanUtil.copyCreateProperties(updateCustHealthInfoDTO, HealthBodyRecord.class);
//         healthBodyRecord.setId(Id.next());
//         healthBodyRecord.setHealthInfoSource(HealthInfoSourceEnum.scales.key());
//         this.healthBodyRecordService.insertLatestRecord(healthBodyRecord);
//         return healthInfoSimpleVo;
//      }
//   }
//
//   public List<CustChronic> queryAllCustChronic() {
//      return (List)this.healthChronicService.getAllChronic().stream().map((s) -> {
//         CustChronic custChronic = new CustChronic();
//         custChronic.setId(s.getId());
//         custChronic.setChronicId(s.getChronicId());
//         custChronic.setChronicName(s.getChronicName());
//         return custChronic;
//      }).collect(Collectors.toList());
//   }
//
//   public void modifyHealthy(HealthInfoFullDto healthInfoFullDto) {
//      this.healthInfoService.editHealthInfo(healthInfoFullDto);
//   }
//
//   public HealthInfoFullVo getHealthyById(Long custId) {
//      HealthInfoFullVo healthInfoFullVo = this.healthInfoService.detailHealthInfo(custId);
//      return healthInfoFullVo;
//   }
//
//   public PageVO<HealthBodyRecordPageVO> pageHealthMonitoring(HealthMonitoringPageDTO monitoringPageDTO) {
//      return this.healthBodyRecordService.pageHealthMonitoring(monitoringPageDTO);
//   }

   public PersonalNutritionAnalyseVO getPersonalNutritionAnalyse(PersonalNutritionAnalyseDTO content) {
      PersonalNutritionAnalyseVO.PersonalNutritionAnalyseVOBuilder builder = PersonalNutritionAnalyseVO.builder();
      String serialNum = content.getSerialNum();
      Long custId = content.getCustId();
      Integer analyseScope = content.getAnalyseScope();
      if (StrUtil.isNotBlank(serialNum)) {
         custId = this.cardInfoServiceV4Api.queryCustIdBySerialNum(serialNum);
      }

      Assert.notNull(custId, () -> {
         return new ServiceException(I18n.getMessage("nutrition.no-cust", new Object[0]));
      });
      CustInfo custInfo = this.custInfoApi.getCustInfoByCustId(custId);
      Assert.notNull(custInfo, () -> {
         return new ServiceException(I18n.getMessage("nutrition.no-cust", new Object[0]));
      });
      LocalDate now = LocalDate.now();
      HealthNormalElementsVo actual;
      if (NumberUtil.equals((long)analyseScope, 2L)) {
         actual = this.healthDishesNutritionService.getNormalElements(custId, now, now.plusDays(6L), false);
      } else {
         actual = this.healthDishesNutritionService.getNormalElements(custId, now, now, false);
      }

      NutrReferenceIntakeVO custIntake = (NutrReferenceIntakeVO)Optional.ofNullable(this.healthCateringService.getCustIntake(custId)).orElse(new NutrReferenceIntakeVO());
      builder.custName(custInfo.getCustName()).age(custInfo.getAge()).orgFullName(custInfo.getOrgFullName()).calories(actual.getCalories()).protein(actual.getProtein()).fat(actual.getFat()).carbohydrate(actual.getCarbohydrate()).dietaryFiber(actual.getDietaryFiber()).cholesterol(actual.getCholesterol()).referenceCalories(NuConvertUtil.toTwo(custIntake.getCalories())).referenceProtein(NuConvertUtil.toTwo(custIntake.getProtein())).referenceFat(NuConvertUtil.toTwo(custIntake.getFat())).referenceCarbohydrate(NuConvertUtil.toTwo(custIntake.getCarbohydrate())).referenceDietaryFiber(NuConvertUtil.toTwo(custIntake.getDietaryFiber())).cholesterol(NuConvertUtil.toTwo(custIntake.getCholesterol())).caloriesIndex(this.getIndex(actual.getCalories(), NuConvertUtil.toTwo(custIntake.getCalories()))).proteinIndex(this.getIndex(actual.getProtein(), NuConvertUtil.toTwo(custIntake.getProtein()))).fatIndex(this.getIndex(actual.getFat(), NuConvertUtil.toTwo(custIntake.getFat()))).carbohydrateIndex(this.getIndex(actual.getCarbohydrate(), NuConvertUtil.toTwo(custIntake.getCarbohydrate()))).dietaryFiberIndex(this.getIndex(actual.getDietaryFiber(), NuConvertUtil.toTwo(custIntake.getDietaryFiber()))).cholesterolIndex(this.getIndex(actual.getCholesterol(), NuConvertUtil.toTwo(custIntake.getCholesterol())));
      return builder.build();
   }

   private BigDecimal getIndex(BigDecimal actual, BigDecimal standard) {
      return !ObjectUtil.isNull(standard) && !NumberUtil.equals(standard, BigDecimal.ZERO) ? NumberUtil.div(actual, standard, NutritionConstants.NEW_SCALE, RoundingMode.HALF_UP) : BigDecimal.ZERO.setScale(NutritionConstants.NEW_SCALE, RoundingMode.HALF_UP);
   }
}
