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

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bonus.canteen.core.nutrition.common.dto.HealthCustMedicalReportEditDTO;
import com.bonus.canteen.core.nutrition.mapper.HealthCustMedicalReportDetailMapper;
import com.bonus.canteen.core.nutrition.mapper.HealthCustMedicalReportMapper;
import com.bonus.canteen.core.nutrition.mapper.HealthCustMedicalReportProMapper;
import com.bonus.canteen.core.nutrition.common.model.HealthCustMedicalReport;
import com.bonus.canteen.core.nutrition.common.model.HealthCustMedicalReportDetail;
import com.bonus.canteen.core.nutrition.common.model.HealthCustMedicalReportProject;
import com.bonus.canteen.core.nutrition.common.vo.HealthCustMedicalReportDetailVO;
import com.bonus.canteen.core.nutrition.common.vo.HealthCustMedicalReportProjectVO;
import com.bonus.canteen.core.nutrition.common.vo.HealthCustMedicalReportVO;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.houqin.i18n.I18n;
import com.bonus.common.houqin.utils.LeBeanUtil;
import com.bonus.common.houqin.utils.id.Id;
import com.bonus.common.security.utils.SecurityUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Iterator;
import java.util.List;

@Service
public class HealthCustMedicalReportService {
   @Resource
   private HealthCustMedicalReportMapper healthCustMedicalReportMapper;
   @Resource
   private HealthCustMedicalReportProMapper healthCustMedicalReportProMapper;
   @Resource
   private HealthCustMedicalReportDetailMapper healthCustMedicalReportDetailMapper;

   public List<HealthCustMedicalReportVO> listMedicalReport() {
      List<HealthCustMedicalReportVO> reportVOList = this.healthCustMedicalReportMapper.listMedicalReport(SecurityUtils.getUserId());
      return reportVOList;
   }

   public List<HealthCustMedicalReportProjectVO> getMedicalReportInfo(Long medicalId) {
      List<HealthCustMedicalReportProjectVO> reportProjectVOS = this.healthCustMedicalReportMapper.listCustReport(medicalId);
      if (CollectionUtil.isEmpty(reportProjectVOS)) {
         return reportProjectVOS;
      } else {
         Iterator ite = reportProjectVOS.iterator();

         while(ite.hasNext()) {
            HealthCustMedicalReportProjectVO project = (HealthCustMedicalReportProjectVO)ite.next();
            List<HealthCustMedicalReportDetailVO> reportDetailVOS = this.healthCustMedicalReportDetailMapper.listCustReportDetail(project.getMedicalProjectId(), medicalId);
            project.setMedicalReportDetailVOList(reportDetailVOS);
         }

         return reportProjectVOS;
      }
   }

   public Long editMedicalReport(HealthCustMedicalReportEditDTO reportEditDTO) {
      Long count = this.healthCustMedicalReportMapper.selectCount(Wrappers.lambdaQuery(HealthCustMedicalReport.class)
              .eq(HealthCustMedicalReport::getMedicalDate, reportEditDTO.getMedicalDate())
              .eq(HealthCustMedicalReport::getMedicalTemplateId, reportEditDTO.getMedicalTemplateId())
              .eq(HealthCustMedicalReport::getUserId, reportEditDTO.getUserId()));
      Long medicalId = reportEditDTO.getMedicalId();
      if (ObjectUtil.isNotEmpty(medicalId)) {
         if (count > 1L) {
            throw new ServiceException("健康监测记录已存在");
         }

         this.deleteMedicalReport(medicalId);
      } else {
         if (count > 0L) {
            throw new ServiceException("健康监测记录已存在");
         }

         medicalId = Id.next();
         reportEditDTO.setMedicalId(medicalId);
      }

      HealthCustMedicalReport report = (HealthCustMedicalReport) LeBeanUtil.copyCreateProperties(reportEditDTO, HealthCustMedicalReport.class);
      this.healthCustMedicalReportMapper.insert(report);
      if (ObjectUtil.isEmpty(reportEditDTO.getReportProjectVOS())) {
         return medicalId;
      } else {
         Iterator iterator = reportEditDTO.getReportProjectVOS().iterator();

         while(true) {
            HealthCustMedicalReportProjectVO projectEditDTO;
            do {
               if (!iterator.hasNext()) {
                  return medicalId;
               }

               projectEditDTO = (HealthCustMedicalReportProjectVO)iterator.next();
               HealthCustMedicalReportProject reportProject = new HealthCustMedicalReportProject();
               reportProject.setMedicalId(medicalId);
               reportProject.setMedicalProjectId(projectEditDTO.getMedicalProjectId());
               reportProject.setMedicalProjectName(projectEditDTO.getMedicalProjectName());
               this.healthCustMedicalReportProMapper.insert(reportProject);
            } while(CollectionUtil.isEmpty(projectEditDTO.getMedicalReportDetailVOList()));

            Iterator ite = projectEditDTO.getMedicalReportDetailVOList().iterator();

            while(ite.hasNext()) {
               HealthCustMedicalReportDetailVO detailEditDTO = (HealthCustMedicalReportDetailVO)ite.next();
               HealthCustMedicalReportDetail reportDetail = new HealthCustMedicalReportDetail();
               reportDetail.setMedicalId(medicalId);
               reportDetail.setMedicalProjectId(projectEditDTO.getMedicalProjectId());
               reportDetail.setMedicalProjectDetailId(detailEditDTO.getMedicalProjectDetailId());
               reportDetail.setMedicalProjectDetailName(detailEditDTO.getMedicalProjectDetailName());
               reportDetail.setResult(detailEditDTO.getResult());
               this.healthCustMedicalReportDetailMapper.insert(reportDetail);
            }
         }
      }
   }

   public void deleteMedicalReport(Long medicalId) {
      this.healthCustMedicalReportMapper.deleteCustReport(medicalId);
      this.healthCustMedicalReportProMapper.delete((Wrapper)Wrappers.lambdaQuery(HealthCustMedicalReportProject.class)
              .eq(HealthCustMedicalReportProject::getMedicalId, medicalId));
      this.healthCustMedicalReportMapper.delete((Wrapper)Wrappers.lambdaQuery(HealthCustMedicalReport.class).eq(HealthCustMedicalReport::getMedicalId, medicalId));
   }

}
