package com.supervision.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.supervision.exception.BusinessException;
import com.supervision.model.*;
import com.supervision.model.Process;
import com.supervision.pojo.vo.ChooseNode;
import com.supervision.pojo.vo.DiagnosticBasisForPrimaryReqVO;
import com.supervision.pojo.vo.RecordForPrimaryChooseVO;
import com.supervision.pojo.vo.SaveDiagnosisPrimaryReqVO;
import com.supervision.vo.ask.*;
import com.supervision.service.*;
import com.supervision.util.UserUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class AskPrimaryServiceImpl implements AskPrimaryService {

    private final DiagnosisPrimaryService diagnosisPrimaryService;

    private final DiseaseService diseaseService;

    private final DiagnosisAncillaryRecordService diagnosisAncillaryRecordService;

    private final DiagnosisPhysicalRecordService diagnosisPhysicalRecordService;

    private final DiagnosisQaRecordService diagnosisQaRecordService;

    private final ProcessService processService;

    private final DiagnosisPrimaryRelationService diagnosisPrimaryRelationService;

    @Override
    public List<DiagnosisPrimaryVO> queryAskPrimaryList(String processId) {
        return diagnosisPrimaryService.queryAskPrimaryList(processId);
    }

    @Override
    public List<Disease> queryPrimaryCanChooseList() {
        return diseaseService.list();
    }

    @Override
    public void modifyPrimaryDiseaseInfo(ModifyPrimaryDiseaseInfoReqVO reqVO) {
        diagnosisPrimaryService.lambdaUpdate().set(DiagnosisPrimary::getPatientDiseaseInfo, reqVO.getPatientDiseaseInfo())
                .eq(DiagnosisPrimary::getId, reqVO.getId()).update();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void savePrimary(SaveDiagnosisPrimaryReqVO reqVO) {
        DiagnosisPrimary diagnosisPrimary = BeanUtil.toBean(reqVO, DiagnosisPrimary.class);
        diagnosisPrimary.setExcludeFlag(null);
        diagnosisPrimary.setCreateUserId(UserUtil.getUser().getId());
        diagnosisPrimaryService.save(diagnosisPrimary);
        // 然后开始保存初步诊断关键的诊断
        if (CollUtil.isNotEmpty(reqVO.getAskIdList())){
            List<DiagnosisPrimaryRelation> askRelationList = reqVO.getAskIdList().stream().map(e -> {
                DiagnosisPrimaryRelation relation = new DiagnosisPrimaryRelation();
                relation.setProcessId(diagnosisPrimary.getProcessId());
                relation.setPrimaryId(diagnosisPrimary.getId());
                relation.setType(1);
                relation.setRelationId(e);
                relation.setCreateUserId(UserUtil.getUser().getId());
                return relation;
            }).collect(Collectors.toList());
            diagnosisPrimaryRelationService.saveBatch(askRelationList);

        }

        if (CollUtil.isNotEmpty(reqVO.getPhysicalIdList())){
            List<DiagnosisPrimaryRelation> physicalRelationList = reqVO.getPhysicalIdList().stream().map(e -> {
                DiagnosisPrimaryRelation relation = new DiagnosisPrimaryRelation();
                relation.setProcessId(diagnosisPrimary.getProcessId());
                relation.setPrimaryId(diagnosisPrimary.getId());
                relation.setType(2);
                relation.setRelationId(e);
                relation.setCreateUserId(UserUtil.getUser().getId());
                return relation;
            }).collect(Collectors.toList());
            diagnosisPrimaryRelationService.saveBatch(physicalRelationList);

        }

        if (CollUtil.isNotEmpty(reqVO.getAncillaryIdList())){
            List<DiagnosisPrimaryRelation> ancillaryRelationList = reqVO.getAncillaryIdList().stream().map(e -> {
                DiagnosisPrimaryRelation relation = new DiagnosisPrimaryRelation();
                relation.setProcessId(diagnosisPrimary.getProcessId());
                relation.setPrimaryId(diagnosisPrimary.getId());
                relation.setType(3);
                relation.setRelationId(e);
                relation.setCreateUserId(UserUtil.getUser().getId());
                return relation;
            }).collect(Collectors.toList());
            diagnosisPrimaryRelationService.saveBatch(ancillaryRelationList);

        }
    }

    @Override
    public RecordForPrimaryChooseVO queryRecordForPrimaryChoose(String processId) {
        RecordForPrimaryChooseVO resVO = new RecordForPrimaryChooseVO();
        // 查询语音问诊记录
        List<DiagnosisQaRecord> list = diagnosisQaRecordService.lambdaQuery().eq(DiagnosisQaRecord::getProcessId, processId).orderByAsc(DiagnosisQaRecord::getCreateTime).list();
        List<ChooseNode> askRecordList = list.stream().map(e -> {
            ChooseNode chooseNode = new ChooseNode();
            chooseNode.setNodeId(e.getId());
            chooseNode.setName(e.getQuestion());
            return chooseNode;

        }).collect(Collectors.toList());
        resVO.setAskList(askRecordList);
        // 查询体格检查记录
        List<AskPhysicalHistoryResVO> physicalHistoryList = diagnosisPhysicalRecordService.queryAskPhysicalHistory(processId);
        List<ChooseNode> physicalList = physicalHistoryList.stream().map(e -> {
            ChooseNode chooseNode = new ChooseNode();
            chooseNode.setNodeId(e.getId());
            chooseNode.setName(StrUtil.join(" | ", e.getToolName(), e.getLocationName()));
            return chooseNode;
        }).collect(Collectors.toList());
        resVO.setPhysicalList(physicalList);
        List<AskAncillaryHistoryResVO> ancillaryHistoryList = diagnosisAncillaryRecordService.queryAncillaryRecord(processId);
        List<ChooseNode> ancillaryList = ancillaryHistoryList.stream().map(e -> {
            ChooseNode chooseNode = new ChooseNode();
            chooseNode.setNodeId(e.getId());
            chooseNode.setName(e.getItemName());
            return chooseNode;
        }).collect(Collectors.toList());
        resVO.setAncillaryList(ancillaryList);
        return resVO;
    }

    @Override
    public RecordForPrimaryChooseVO queryPrimaryChooseList(String processId, String primaryId) {
        RecordForPrimaryChooseVO resVO = queryRecordForPrimaryChoose(processId);
        // 获取relation表的数据
        List<DiagnosisPrimaryRelation> relationList = diagnosisPrimaryRelationService.lambdaQuery().eq(DiagnosisPrimaryRelation::getPrimaryId, primaryId).list();
        Set<String> relationSet = relationList.stream().map(DiagnosisPrimaryRelation::getRelationId).collect(Collectors.toSet());
        for (ChooseNode chooseNode : resVO.getAskList()) {
            chooseNode.setChecked(relationSet.contains(chooseNode.getNodeId()));
        }
        for (ChooseNode chooseNode : resVO.getPhysicalList()) {
            chooseNode.setChecked(relationSet.contains(chooseNode.getNodeId()));
        }
        for (ChooseNode chooseNode : resVO.getAncillaryList()) {
            chooseNode.setChecked(relationSet.contains(chooseNode.getNodeId()));
        }
        return resVO;
    }

    @Override
    public void updatePrimaryByConfirm(DiagnosisPrimary reqVO) {
        diagnosisPrimaryService.lambdaUpdate().set(DiagnosisPrimary::getExcludeFlag, reqVO.getExcludeFlag())
                .set(DiagnosisPrimary::getPatientDiseaseInfo, reqVO.getPatientDiseaseInfo())
                .eq(DiagnosisPrimary::getId, reqVO.getId()).update();
    }

    @Override
    public void deletePrimary(String id) {
        // 如果本项初步诊断已经做过了辅助检查和体格检查,则不允许删除
        DiagnosisPrimary primary = diagnosisPrimaryService.getById(id);
        Integer ancillaryCount = diagnosisAncillaryRecordService.lambdaQuery().eq(DiagnosisAncillaryRecord::getProcessId, primary.getProcessId()).count();
        if (ancillaryCount > 0) {
            throw new BusinessException("仅支持删除没有做过体格、辅助检查的初步诊断项目");
        }
        Integer physicalCount = diagnosisPhysicalRecordService.lambdaQuery().eq(DiagnosisPhysicalRecord::getProcessId, primary.getProcessId()).count();
        if (physicalCount > 0) {
            throw new BusinessException("仅支持删除没有做过体格、辅助检查的初步诊断项目");
        }
        diagnosisPrimaryService.lambdaUpdate().eq(DiagnosisPrimary::getId, id).remove();
    }

    /**
     * 确诊页面,初步诊断填写初步诊断依据
     *
     * @param processId 流程ID
     * @return 结果
     */
    @Override
    public List<DiagnosticBasisForPrimaryResVO> queryDiagnosticBasisListForPrimary(String processId) {
        List<DiagnosticBasisForPrimaryResVO> resList = diagnosisPrimaryService.queryDiagnosticBasisListForPrimary(processId);
        if (CollUtil.isEmpty(resList)) {
            return resList;
        }
        // 找到process对应的所有的初步诊断
        List<DiagnosisPrimaryVO> diagnosisPrimaryVOS = diagnosisPrimaryService.queryAskPrimaryList(processId);
        Map<String, String> diseaseNameMap = diagnosisPrimaryVOS.stream().collect(Collectors.toMap(DiagnosisPrimaryVO::getId, DiagnosisPrimaryVO::getPrimaryDiseaseName));
        // 首先根据诊断记录,找到对应的关联关系
        Set<String> relationIdSet = resList.stream().map(DiagnosticBasisForPrimaryResVO::getId).collect(Collectors.toSet());
        List<DiagnosisPrimaryRelation> relationList = diagnosisPrimaryRelationService.lambdaQuery().in(DiagnosisPrimaryRelation::getRelationId, relationIdSet).list();
        // 根据relationId进行分组
        Map<String, List<DiagnosisPrimaryRelation>> relationMap = relationList.stream().collect(Collectors.groupingBy(DiagnosisPrimaryRelation::getRelationId));
        for (DiagnosticBasisForPrimaryResVO node : resList) {
            List<DiagnosisPrimaryRelation> relationPrimaryList = relationMap.get(node.getId());
            Set<String> primarySet = relationPrimaryList.stream().map(DiagnosisPrimaryRelation::getPrimaryId).collect(Collectors.toSet());
            if (CollUtil.isNotEmpty(primarySet)) {
                List<String> diseaseNameList = new ArrayList<>();
                primarySet.forEach(e -> diseaseNameList.add(diseaseNameMap.get(e)));
                node.setPrimaryIdList(new ArrayList<>(primarySet));
                node.setPrimaryName(StrUtil.join(";", diseaseNameList));
            }

        }

        return resList;
    }

    @Override
    public void saveDiagnosticBasis(List<DiagnosticBasisForPrimaryReqVO> reqVO) {
        for (DiagnosticBasisForPrimaryReqVO node : reqVO) {
            if (1 == node.getType()) {
                diagnosisQaRecordService.lambdaUpdate().set(DiagnosisQaRecord::getBasisConfirmFlag, node.getBasisConfirmFlag())
                        .set(DiagnosisQaRecord::getBasisIdentificationFlag, node.getBasisIdentificationFlag())
                        .eq(DiagnosisQaRecord::getId, node.getId()).update();
                continue;
            }
            if (2 == node.getType()) {
                diagnosisPhysicalRecordService.lambdaUpdate().set(DiagnosisPhysicalRecord::getBasisConfirmFlag, node.getBasisConfirmFlag())
                        .set(DiagnosisPhysicalRecord::getBasisIdentificationFlag, node.getBasisIdentificationFlag())
                        .eq(DiagnosisPhysicalRecord::getId, node.getId()).update();
                continue;
            }
            if (3 == node.getType()) {
                diagnosisAncillaryRecordService.lambdaUpdate().set(DiagnosisAncillaryRecord::getBasisConfirmFlag, node.getBasisConfirmFlag())
                        .set(DiagnosisAncillaryRecord::getBasisIdentificationFlag, node.getBasisIdentificationFlag())
                        .eq(DiagnosisAncillaryRecord::getId, node.getId()).update();
            }

        }
        // 然后将process的状态改为诊毕
        processService.lambdaUpdate().set(Process::getStatus, 1).update();
    }
}