package com.docus.server.collection.service.impl;

import com.docus.core.util.Func;
import com.docus.infrastructure.web.api.CommonResult;
import com.docus.infrastructure.web.api.ResultCode;
import com.docus.server.collection.config.SystemMappingConfig;
import com.docus.server.collection.dto.FirstPageCheckoutInDTO;
import com.docus.server.collection.dto.PatientInfoDTO;
import com.docus.server.collection.entity.CollectSysDictionary;
import com.docus.server.collection.enums.FileSyncMethod;
import com.docus.server.collection.feign.dto.CompensateTasRequest;
import com.docus.server.collection.feign.service.CollectTaskService;
import com.docus.server.collection.feign.service.MedicalrecordService;
import com.docus.server.collection.infrastructure.dao.mapper.CollectSysDictionaryMapper;
import com.docus.server.collection.infrastructure.dao.mapper.TBasicMapper;
import com.docus.server.collection.service.MzZyHisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author wyb
 */
@Slf4j
@Service
public class MzZyHisServiceImpl implements MzZyHisService {
    @Resource
    private CollectTaskService collectTaskService;
    @Resource
    private CollectSysDictionaryMapper collectSysDictionaryMapper;
    @Resource
    private TBasicMapper tBasicMapper;

    @Resource
    private MedicalrecordService medicalrecordService;

    @Override
    public void firstPageCheckout(FirstPageCheckoutInDTO dto) {
        PatientInfoDTO patientInfo = dto.getPatientInfo();
        //验证基础数据是否存在
        String patientId = tBasicMapper.getPatientIdByJzh(patientInfo.getInpatientNo());
        if (Func.isBlank(patientId)) {
            throw new RuntimeException("系统未找到患者数据,住院流水号:" + patientInfo.getInpatientNo());
        }
        // 取得映射结果后的无纸化系统id
        List<String> collectorIds = systemMappingCollectorIds(dto);
        // 进行任务补偿
        CompensateTasRequest request = new CompensateTasRequest();
        request.setPriority(3);
        request.setPatientIds(Collections.singletonList(patientId));
        request.setCollectorIds(collectorIds);
        CommonResult<String> commonResult = collectTaskService.compensateTask(request);
        // 抛出异常，进行参数持久
        if (commonResult.getCode().equals(ResultCode.FAILED.getCode())) {
            throw new RuntimeException(commonResult.getMsg());
        }
        CommonResult result = medicalrecordService.signOutOrBackRepair(patientId);
        // 抛出异常，进行参数持久
        if (result.getCode().equals(ResultCode.FAILED.getCode())) {
            throw new RuntimeException(commonResult.getMsg());
        }
        babyTaskCompensate(patientInfo.getInpatientNo(),collectorIds);
    }

    @Override
    public List<String> getPid() {
        return tBasicMapper.getPid();
    }

    /**
     * 根据母亲的住院流水号，查询宝宝的病案主键，进行任务补偿
     * @param momJzh 母亲住院流水号
     * @param collectorIds 采集器id
     */
    private void babyTaskCompensate(String momJzh, List<String> collectorIds) {
        List<String> babyPatientIds=tBasicMapper.getPatientIdByMomJzh(momJzh);
        if(Func.isNotEmpty(babyPatientIds)){
            // 进行任务补偿
            CompensateTasRequest request = new CompensateTasRequest();
            request.setPatientIds(babyPatientIds);
            request.setPriority(2);
            request.setCollectorIds(collectorIds);
            collectTaskService.compensateTask(request);
            for (String babyPatientId : babyPatientIds) {
                medicalrecordService.signOutOrBackRepair(babyPatientId);
            }
        }
    }

    private List<String> systemMappingCollectorIds(FirstPageCheckoutInDTO dto) {
        // 取得无纸化系统所有的采集系统配置
        List<CollectSysDictionary> wzhAllCollectSys = getWzhAllCollectSys();
        if (Func.isEmpty(wzhAllCollectSys)) {
            throw new RuntimeException("文件同步，未配置系统！");
        }
        List<String> wzhAllCollectSysCode = wzhAllCollectSys.stream()
                .map(CollectSysDictionary::getSysCode)
                .distinct().collect(Collectors.toList());
        // 文件同步方式，如果是按照系统，则匹配系统，否则取无纸化系统所有的采集系统配置
        if (dto.getSyncMethod() == FileSyncMethod.BY_SYS_ID) {
            // 医院的系统id
            List<String> hospSysIds = dto.getSysId();
            // 映射之后的系统id
            List<String> collectorIds = new ArrayList<>();
            // 映射配置读取
            SystemMappingConfig instance = SystemMappingConfig.getInstance();
            List<SystemMappingConfig.SystemMapping> systemMappingList = instance.getMappings();
            validateSystemMappingConfig(systemMappingList);
            // 按照医院的id分组
            Map<String, List<SystemMappingConfig.SystemMapping>> mappingGroupHosp = systemMappingList.stream().collect(Collectors.groupingBy(SystemMappingConfig.SystemMapping::getHospital));
            for (String hospSysId : hospSysIds) {
                List<SystemMappingConfig.SystemMapping> mappingListByHospSysId = mappingGroupHosp.get(hospSysId);
                if (Func.isEmpty(mappingListByHospSysId)) {
                    throw new RuntimeException("系统id：" + hospSysId + " 配置映射失败！");
                }
                // 映射无纸化系统，验证是否都属于无纸化系统
                List<String> mappingWzhSys = mappingListByHospSysId.stream().map(SystemMappingConfig.SystemMapping::getWzh).collect(Collectors.toList());
                if (wzhAllCollectSysCode.containsAll(mappingWzhSys)) {
                    collectorIds.addAll(mappingWzhSys);
                    continue;
                }
                throw new RuntimeException("系统id：" + hospSysId + " 配置映射错误！");
            }
            // 去重
            return collectorIds.stream().distinct().collect(Collectors.toList());
        }
        return wzhAllCollectSysCode;
    }

    private List<CollectSysDictionary> getWzhAllCollectSys() {
        return collectSysDictionaryMapper.findAll();
    }

    /**
     * 验证配置的映射 不为空，且每个映射对象不为空
     *
     * @param mappings
     */
    private void validateSystemMappingConfig(List<SystemMappingConfig.SystemMapping> mappings) {
        if (Func.isEmpty(mappings)) {
            throw new RuntimeException("系统映射配置错误！");
        }
        for (SystemMappingConfig.SystemMapping mapping : mappings) {
            if (Func.isBlank(mapping.getHospital()) || Func.isBlank(mapping.getWzh())) {
                throw new RuntimeException("系统映射配置错误！");
            }
        }
    }
}
