package com.eitc.patient.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eitc.common.utils.bean.BeanUtils;
import com.eitc.patient.domain.MedicalHistory;
import com.eitc.patient.domain.Patient;
import com.eitc.patient.enums.MedicalHistoryDiseaseSourceEnum;
import com.eitc.patient.mapper.PatientMapper;
import com.eitc.patient.service.IMedicalHistoryService;
import com.eitc.patient.service.IPatientService;
import com.eitc.patient.utils.PatientUtil;
import com.eitc.patient.vo.PatientVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * PatientServiceImpl
 *
 * @author mtx
 * @date: 2024/05/17 15:40
 */
@Service
public class PatientServiceImpl extends ServiceImpl<PatientMapper, Patient> implements IPatientService {

    @Resource
    private IMedicalHistoryService medicalHistoryService;


    /**
     * 添加或编辑患者信息。
     * 通过接收PatientVO对象，复制属性到新的Patient对象中。如果患者ID为空，则生成新的医疗记录号。
     * 保存或更新患者信息，并根据PatientVO中的病史信息创建相应的病历。
     *
     * @param vo 患者信息VO，包含患者的基本信息和病史信息。
     * @return 返回保存或更新后的患者实体。
     * @author mtx
     * @date 2024/5/22 9:12
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Patient addOrEdit(PatientVO vo) {
        // 创建一个新的Patient对象，并从PatientVO中复制属性。
        Patient patient = new Patient();
        BeanUtils.copyProperties(vo, patient);

        // 如果患者ID为空，生成新的医疗记录号。
        if (StringUtils.isEmpty(patient.getId())) {
            patient.setMedicalRecordNum(findMedicalRecordNum());
        }

        // 保存或更新患者信息。
        this.saveOrUpdate(patient);

        // 根据PatientVO中的病史信息，保存相应的病历。
        medicalHistoryService.saveMedicalHistoryList(
                vo.getAllergyHistory(),
                vo.getPastHistory(),
                vo.getFamilyHistory(),
                null,
                patient.getId(),
                MedicalHistoryDiseaseSourceEnum.PATIENT.getCode());

        return patient;
    }

    /**
     * 获取一个新的用户编号，确保该用户编号在系统中是唯一的。
     * 本方法通过调用PatientUtil的findMedicalRecordNum方法来获取一个初始的用户编号，
     * 然后检查系统中是否已存在该用户编号，如果存在，则继续调用findMedicalRecordNum获取新的用户编号，
     * 直到找到一个在系统中不存在的用户编号为止。
     * 这种方式可以保证返回的用户编号在系统中是唯一的，避免了用户编号重复的问题。
     *
     * @return 新的、在系统中唯一的用户编号。
     */
    @Override
    public String findMedicalRecordNum() {
        // 从PatientUtil中获取一个初始的用户编号
        String medicalRecordNum = PatientUtil.findMedicalRecordNum();
        // 循环检查直到找到一个系统中不存在的用户编号
        while (this.count(Wrappers.<Patient>lambdaQuery().eq(Patient::getMedicalRecordNum, medicalRecordNum)) > 0) {
            // 如果当前用户编号已存在，则重新获取一个新的用户编号
            medicalRecordNum = PatientUtil.findMedicalRecordNum();
        }
        // 返回最终获取的、系统中不存在的用户编号
        return medicalRecordNum;
    }



    /**
     * 删除患者
     *
     * @param ids ids
     * @return 状态
     * @author mtx
     * @date: 2024/5/22 9:40
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean delete(List<String> ids) {
        // 删除患者
        this.removeBatchByIds(ids);
        // 删除病历
        return medicalHistoryService.remove(Wrappers.<MedicalHistory>lambdaQuery().in(MedicalHistory::getPatientId, ids));
    }
}
