package com.eitc.patient.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eitc.patient.domain.MedicalHistory;
import com.eitc.patient.dto.DiagnosisTypeTemplateDto;
import com.eitc.patient.enums.MedicalHistoryDiseaseSourceEnum;
import com.eitc.patient.enums.MedicalHistoryDiseaseTypeEnum;
import com.eitc.patient.mapper.MedicalHistoryMapper;
import com.eitc.patient.service.IMedicalHistoryService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * MedicalHistoryServiceImpl
 *
 * @author mtx
 * @date: 2024/05/21 17:28
 */
@Service
public class MedicalHistoryServiceImpl extends ServiceImpl<MedicalHistoryMapper, MedicalHistory> implements IMedicalHistoryService {

    /**
     * 获取病史列表
     *
     * @param contents        病史内容
     * @param medicalRecordId 病历id
     * @param patientId       患者id
     * @param diseaseType     病史类型
     * @param diseaseSource   病史来源
     * @return 病史列表
     * @author mtx
     * @date: 2024/5/22 9:15
     */
    @Override
    public List<MedicalHistory> encapsulationMedicalHistoryList(String contents,
                                                                String medicalRecordId,
                                                                String patientId,
                                                                Integer diseaseType,
                                                                Integer diseaseSource) {

        if (StringUtils.isBlank(contents)) {
            return new ArrayList<>();
        }
        return Arrays.stream(contents.split(",")).map(content -> {
            MedicalHistory medicalHistory = new MedicalHistory();
            medicalHistory.setDiseaseContent(content);
            medicalHistory.setDiseaseType(diseaseType);
            medicalHistory.setMedicalRecordId(medicalRecordId);
            medicalHistory.setPatientId(patientId);
            medicalHistory.setDiseaseSource(diseaseSource);
            return medicalHistory;
        }).collect(Collectors.toList());
    }

    /**
     * 封装病史列表
     *
     * @param allergyHistory  过敏史
     * @param pastHistory     既往史
     * @param familyHistory   家族史
     * @param medicalRecordId 病历id
     * @param patientId       患者id
     * @param diseaseSource   来源
     * @author mtx
     * @date: 2024/5/22 10:18
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void saveMedicalHistoryList(String allergyHistory,
                                       String pastHistory,
                                       String familyHistory,
                                       String medicalRecordId,
                                       String patientId,
                                       Integer diseaseSource) {
        List<MedicalHistory> all = new ArrayList<>();
        // 封装过敏史
        if (Objects.nonNull(allergyHistory)) {
            all.addAll(encapsulationMedicalHistoryList(
                    allergyHistory,
                    medicalRecordId,
                    patientId,
                    MedicalHistoryDiseaseTypeEnum.ALLERGY_HISTORY.getCode(),
                    diseaseSource
            ));
            this.remove(Wrappers.<MedicalHistory>lambdaQuery()
                    .eq(MedicalHistory::getDiseaseType, MedicalHistoryDiseaseTypeEnum.ALLERGY_HISTORY.getCode())
                    .eq(MedicalHistory::getDiseaseSource, diseaseSource)
                    .eq(Objects.nonNull(patientId), MedicalHistory::getPatientId, patientId)
                    .eq(Objects.nonNull(medicalRecordId), MedicalHistory::getMedicalRecordId, medicalRecordId));
        }
        // 封装既往史
        if (Objects.nonNull(pastHistory)) {
            all.addAll(encapsulationMedicalHistoryList(
                    pastHistory,
                    medicalRecordId,
                    patientId,
                    MedicalHistoryDiseaseTypeEnum.PAST_HISTORY.getCode(),
                    diseaseSource
            ));
            this.remove(Wrappers.<MedicalHistory>lambdaQuery()
                    .eq(MedicalHistory::getDiseaseType, MedicalHistoryDiseaseTypeEnum.PAST_HISTORY.getCode())
                    .eq(MedicalHistory::getDiseaseSource, diseaseSource)
                    .eq(Objects.nonNull(patientId), MedicalHistory::getPatientId, patientId)
                    .eq(Objects.nonNull(medicalRecordId), MedicalHistory::getMedicalRecordId, medicalRecordId));
        }
        // 封装家族史
        if (Objects.nonNull(familyHistory)) {
            all.addAll(encapsulationMedicalHistoryList(
                    familyHistory,
                    medicalRecordId,
                    patientId,
                    MedicalHistoryDiseaseTypeEnum.FAMILY_HISTORY.getCode(),
                    diseaseSource
            ));
            this.remove(Wrappers.<MedicalHistory>lambdaQuery()
                    .eq(MedicalHistory::getDiseaseType, MedicalHistoryDiseaseTypeEnum.FAMILY_HISTORY.getCode())
                    .eq(MedicalHistory::getDiseaseSource, diseaseSource)
                    .eq(Objects.nonNull(patientId), MedicalHistory::getPatientId, patientId)
                    .eq(Objects.nonNull(medicalRecordId), MedicalHistory::getMedicalRecordId, medicalRecordId));
        }

        this.saveBatch(all);
    }

    /**
     * 查询患者的病史保存到历史记录中
     *
     * @param patientId       患者id
     * @param medicalRecordId 病历id
     * @author mtx
     * @date: 2024/5/22 13:57
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void saveMedicalHistoryToMedicalRecordIdByPatientId(String patientId, String medicalRecordId) {
        // 查询患者保存的病史
        List<MedicalHistory> list = this.list(Wrappers.<MedicalHistory>lambdaQuery().eq(MedicalHistory::getPatientId, patientId));
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        // 封装并保存记录
        List<MedicalHistory> lists = list.stream().map(item -> {
            MedicalHistory medicalHistory = new MedicalHistory();
            medicalHistory.setMedicalRecordId(medicalRecordId);
            medicalHistory.setDiseaseType(item.getDiseaseType());
            medicalHistory.setDiseaseContent(item.getDiseaseContent());
            medicalHistory.setDiseaseSource(MedicalHistoryDiseaseSourceEnum.PATIENT.getCode());
            return medicalHistory;
        }).collect(Collectors.toList());

        this.remove(Wrappers.<MedicalHistory>lambdaQuery()
                .eq(MedicalHistory::getMedicalRecordId, medicalRecordId)
                .eq(MedicalHistory::getDiseaseSource, MedicalHistoryDiseaseSourceEnum.PATIENT.getCode()));
        this.saveBatch(lists);
    }

    /**
     * 根据患者ID、疾病类型和诊断类型模板详情，查询患者的病史信息。
     * 此方法主要用于检索与特定疾病类型和患者相关的病史记录，并根据病史来源筛选出患者自述的病史内容。
     *
     * @param patientId 患者的唯一标识ID，用于查询特定患者的病史记录。
     * @param diseaseType 疾病类型的标识，用于筛选特定类型的病史记录。
     * @param detailsVO 诊断类型模板详情的DTO（数据传输对象），用于接收和存储查询结果。
     *                  此对象将包含患者自述的病史内容列表和这些内容的格式化列表。
     * @author mtx
     * @date 2024/06/07 14:01
     */
    @Override
    public void findMedicalHistory(String patientId, Integer diseaseType, DiagnosisTypeTemplateDto detailsVO) {
        // 根据疾病类型和患者ID查询所有的病史记录
        List<MedicalHistory> histories = this.list(Wrappers.<MedicalHistory>lambdaQuery()
                .eq(MedicalHistory::getDiseaseType, diseaseType)
                .eq(MedicalHistory::getPatientId, patientId));

        // 筛选病史来源为患者自述的病史记录，将病史内容拼接为字符串，用逗号分隔，存储到detailsVO中
        detailsVO.setPatientMedicalRecord(histories.stream()
                .filter(li -> MedicalHistoryDiseaseSourceEnum.PATIENT.getCode().equals(li.getDiseaseSource()))
                .map(MedicalHistory::getDiseaseContent).collect(Collectors.joining(",")));

        // 筛选病史来源为患者自述的病史记录，将病史内容收集到列表中，存储到detailsVO中
        detailsVO.setFormattedPartsList(histories.stream()
                .filter(li -> MedicalHistoryDiseaseSourceEnum.PATIENT.getCode().equals(li.getDiseaseSource()))
                .map(MedicalHistory::getDiseaseContent).collect(Collectors.toList()));
    }


}
