package com.supervision.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.supervision.dto.DiseaseAncillaryDto;
import com.supervision.exception.BusinessException;
import com.supervision.model.*;
import com.supervision.model.Process;
import com.supervision.pojo.vo.AskAncillaryBatchReqVO;
import com.supervision.vo.ask.*;
import com.supervision.pojo.vo.AskAncillaryResultReqVO;
import com.supervision.service.*;
import com.supervision.util.UserUtil;
import com.supervision.vo.result.ConfigAncillaryItemVo;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class AskAncillaryServiceImpl implements AskAncillaryService {

    private final ProcessService processService;

    private final DiseaseAncillaryService diseaseAncillaryService;

    private final ConfigAncillaryItemService ancillaryItemService;

    private final DiagnosisAncillaryRecordService diagnosisAncillaryRecordService;

    private final DiagnosisPrimaryService diagnosisPrimaryService;


    @Override
    public List<ConfigAncillaryItemResVO> queryAncillaryItemList(AncillaryItemReqVo ancillaryItemReqVo) {

        return ancillaryItemService.queryAncillaryItemList(ancillaryItemReqVo);
    }

    @Override
    public Map<String, List<ConfigAncillaryItem>> queryAncillaryItemTree() {
        List<ConfigAncillaryItem> list = ancillaryItemService.list();
        return list.stream().collect(Collectors.groupingBy(ConfigAncillaryItem::getType));
    }

    @Override
    public void execAskAncillaryBatch(List<AskAncillaryBatchReqVO> reqVO) {
        // 首先根据process_id查新到流程ID
        Process process = Optional.ofNullable(processService.getById(reqVO.stream().findAny()
                        .orElseThrow(() -> new BusinessException("流程ID不能为空")).getProcessId()))
                .orElseThrow(() -> new BusinessException("未找到流程ID"));
        for (AskAncillaryBatchReqVO item : reqVO) {
                // 执行并保存结果
                execSaveDiagnosisAncillaryRecord(item.getAncillaryItemId(), item.getPrimaryId(), process);
        }
    }

    @Deprecated
    @Override
    public DiagnosisAncillaryRecordVo execAskAncillaryResult(AskAncillaryResultReqVO reqVO) {
        // 首先根据process_id查新到流程ID
        Process process = Optional.ofNullable(processService.getById(reqVO.getProcessId())).orElseThrow(() -> new BusinessException("未找到流程ID"));
        DiagnosisAncillaryRecord record = execSaveDiagnosisAncillaryRecord(reqVO.getItemId(), CollUtil.newArrayList(reqVO.getPrimaryId()), process);
        //重组返回结果
        DiagnosisAncillaryRecordVo recordVo = BeanUtil.toBean(record, DiagnosisAncillaryRecordVo.class);
        recordVo.setAncillaryName(record.getItemName());
        return recordVo;
    }

    private DiagnosisAncillaryRecord execSaveDiagnosisAncillaryRecord(String itemId, List<String> primaryIdList, Process process) {
        // 找到对应的项目的检查结果
        DiseaseAncillary diseaseAncillaryQueryBean = new DiseaseAncillary();
        diseaseAncillaryQueryBean.setItemId(itemId);
        diseaseAncillaryQueryBean.setDiseaseId(process.getDiseaseId());
        DiseaseAncillaryDto diseaseAncillary = diseaseAncillaryService.queryDiseaseAncillaryDtoOne(diseaseAncillaryQueryBean, () -> {
            DiseaseAncillaryDto get = new DiseaseAncillaryDto();
            get.setResult("无相关资讯");
            return get;
        });

        DiagnosisAncillaryRecord record = new DiagnosisAncillaryRecord();
        record.setProcessId(process.getId());
        record.setItemId(itemId);
        record.setAncillaryId(diseaseAncillary.getId());
        record.setResult(diseaseAncillary.getResult());
        record.setCreateUserId(UserUtil.getUser().getId());
        record.setUpdateUserId(UserUtil.getUser().getId());
        record.insert();
        record.setItemName(diseaseAncillary.getItemName());

        // 保存初步诊断的关联关系
        for (String primaryId : primaryIdList) {
            DiagnosisPrimaryRelation diagnosisPrimaryRelation = new DiagnosisPrimaryRelation();
            diagnosisPrimaryRelation.setProcessId(process.getId());
            diagnosisPrimaryRelation.setPrimaryId(primaryId);
            diagnosisPrimaryRelation.setType(3);
            diagnosisPrimaryRelation.setRelationId(record.getId());
            diagnosisPrimaryRelation.insert();
        }



        return record;
    }

    @Override
    public List<AskAncillaryHistoryResVO> queryAskAncillaryHistory(String processId) {
        List<AskAncillaryHistoryResVO> historyList = diagnosisAncillaryRecordService.queryAncillaryRecord(processId);
        // 找到问诊流程对应的初步诊断项目
        List<DiagnosisPrimaryVO> diagnosisPrimaryVOS = diagnosisPrimaryService.queryAskPrimaryList(processId);
        Map<String, DiagnosisPrimaryVO> primaryMap = diagnosisPrimaryVOS.stream().collect(Collectors.toMap(DiagnosisPrimaryVO::getId, Function.identity()));
        // 这里需要根据item和primaryId进行去重,对于完全相同的,只保留一个,
        Map<String, List<AskAncillaryHistoryResVO>> collect = historyList.stream().collect(Collectors.groupingBy(e -> e.getItemId() + e.getPrimaryId()));
        List<AskAncillaryHistoryResVO> distinctItemIdAndPrimaryIdList = new ArrayList<>();
        collect.values().forEach(e -> {
            Optional<AskAncillaryHistoryResVO> any = e.stream().findAny();
            any.ifPresent(distinctItemIdAndPrimaryIdList::add);
        });
        List<AskAncillaryHistoryResVO> resList = new ArrayList<>();
        // 对于item相同的,primaryId不同的,进行合并
        Map<String, List<AskAncillaryHistoryResVO>> resMap = distinctItemIdAndPrimaryIdList.stream()
                .collect(Collectors.groupingBy(AskAncillaryHistoryResVO::getItemId));

        for (Map.Entry<String, List<AskAncillaryHistoryResVO>> entry : resMap.entrySet()) {
            List<AskAncillaryHistoryResVO> value = entry.getValue();
            List<DiagnosisPrimaryVO> diagnosisPrimaryList = new ArrayList<>();
            Optional<AskAncillaryHistoryResVO> any = value.stream().findAny();
            if (any.isPresent()){
                AskAncillaryHistoryResVO bean = BeanUtil.toBean(any.get(), AskAncillaryHistoryResVO.class);
                for (AskAncillaryHistoryResVO node: value) {
                    DiagnosisPrimaryVO diagnosisPrimaryVO = primaryMap.get(node.getPrimaryId());
                    if (ObjectUtil.isNotEmpty(diagnosisPrimaryVO)){
                        diagnosisPrimaryList.add(diagnosisPrimaryVO);
                    }
                }
                bean.setPrimaryId(null);
                bean.setPrimaryList(diagnosisPrimaryList);
                resList.add(bean);
            }
        }
        return resList;
    }

}