package com.lantone.daqe.facade;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.lantone.common.enums.IsDeleteEnum;
import com.lantone.common.exception.Asserts;
import com.lantone.common.util.BeanUtil;
import com.lantone.common.util.EntityUtil;
import com.lantone.common.util.ListUtil;
import com.lantone.common.util.StringUtil;
import com.lantone.common.vo.DataCompareVO;
import com.lantone.common.vo.DataRepariVO;
import com.lantone.daqe.dto.HisMedicalRecordDTO;
import com.lantone.daqe.dto.HisRecDTO;
import com.lantone.daqe.entity.BehospitalInfo;
import com.lantone.daqe.entity.HisBehospitalInfo;
import com.lantone.daqe.entity.HisHomePage;
import com.lantone.daqe.entity.HisMedicalRecord;
import com.lantone.daqe.entity.HisMedicalRecordContent;
import com.lantone.daqe.entity.HomePage;
import com.lantone.daqe.entity.MedicalRecord;
import com.lantone.daqe.entity.MedicalRecordContent;
import com.lantone.daqe.facade.base.HisBehospitalInfoFacade;
import com.lantone.daqe.facade.base.HisHomePageFacade;
import com.lantone.daqe.facade.base.HisMedicalRecordContentFacade;
import com.lantone.daqe.facade.base.HisMedicalRecordFacade;
import com.lantone.daqe.service.impl.BehospitalInfoServiceImpl;
import com.lantone.daqe.service.impl.HomePageServiceImpl;
import com.lantone.daqe.service.impl.MedicalRecordContentServiceImpl;
import com.lantone.daqe.service.impl.MedicalRecordServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: His数据模拟对接-业务处理类
 * @author: songxl
 * @time: 2022/3/4 10:39
 */
@Component
public class HisDataManagementFacade {
    @Autowired
    private HisBehospitalInfoFacade hisBehospitalInfoFacade;
    @Autowired
    private HisHomePageFacade hisHomePageFacade;
    @Autowired
    private HisMedicalRecordFacade hisMedicalRecordFacade;
    @Autowired
    private HisMedicalRecordContentFacade hisMedicalRecordContentFacade;

    @Autowired
    private BehospitalInfoServiceImpl behospitalInfoServiceImpl;
    @Autowired
    private HomePageServiceImpl homePageServiceImpl;
    @Autowired
    private MedicalRecordServiceImpl medicalRecordServiceImpl;
    @Autowired
    private MedicalRecordContentServiceImpl medicalRecordContentServiceImpl;


    /**
     * 数据补录
     *
     * @param dataRepariVO
     * @Return boolean
     */
    public boolean dataRepari(DataRepariVO dataRepariVO) {
        //=====获取his数据
        //病历数据
        List<HisBehospitalInfo> hisBehospitalInfos = hisBehospitalInfoFacade.list(new QueryWrapper<HisBehospitalInfo>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .ge(dataRepariVO.getStartDate() != null && StringUtil.isBlank(dataRepariVO.getBehospitalCode()), "behospital_date", dataRepariVO.getStartDate())
                .le(dataRepariVO.getEndDate() != null && StringUtil.isBlank(dataRepariVO.getBehospitalCode()), "behospital_date", dataRepariVO.getEndDate())
                .eq(StringUtil.isNotBlank(dataRepariVO.getBehospitalCode()), "behospital_code", dataRepariVO.getBehospitalCode()));
        //通过病历获取病案首页和文书
        if (ListUtil.isEmpty(hisBehospitalInfos)) {
            return true;
        }
        List<String> codes = hisBehospitalInfos.stream().map(HisBehospitalInfo::getBehospitalCode).collect(Collectors.toList());

        //病案首页
        List<HisHomePage> hisHomePages = hisHomePageFacade.list(new QueryWrapper<HisHomePage>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .in("behospital_code", codes));

        //文书
        List<HisMedicalRecord> hisMedicalRecords = hisMedicalRecordFacade.list(new QueryWrapper<HisMedicalRecord>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .in("behospital_code", codes));
        List<HisMedicalRecordContent> hisMedicalRecordContents = null;
        if (ListUtil.isNotEmpty(hisMedicalRecords)) {
            hisMedicalRecordContents = hisMedicalRecordContentFacade.list(new QueryWrapper<HisMedicalRecordContent>()
                    .eq("is_deleted", IsDeleteEnum.N.getKey())
                    .in("rec_id", hisMedicalRecords.stream().map(HisMedicalRecord::getRecId).collect(Collectors.toList())));
        }

        //=====删除以插入病历数据，重新插入
        behospitalInfoServiceImpl.remove(new UpdateWrapper<BehospitalInfo>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .in("behospital_code", codes));
        homePageServiceImpl.remove(new UpdateWrapper<HomePage>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .in("behospital_code", codes));

        //删除文书内容
        List<String> delRecIds = medicalRecordServiceImpl.list(new QueryWrapper<MedicalRecord>().select("rec_id")
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .in("behospital_code", codes))
                .stream().map(MedicalRecord::getRecId).collect(Collectors.toList());
        if (ListUtil.isNotEmpty(delRecIds)) {
            medicalRecordContentServiceImpl.remove(new UpdateWrapper<MedicalRecordContent>()
                    .eq("is_deleted", IsDeleteEnum.N.getKey())
                    .in("rec_id", delRecIds));
        }
        //删除文书
        medicalRecordServiceImpl.remove(new UpdateWrapper<MedicalRecord>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .in("behospital_code", codes));

        //插入新查出的his数据
        try {
            behospitalInfoServiceImpl.saveBatch(BeanUtil.listCopyTo(hisBehospitalInfos, BehospitalInfo.class));
            homePageServiceImpl.saveBatch(BeanUtil.listCopyTo(hisHomePages, HomePage.class));
            medicalRecordServiceImpl.saveBatch(BeanUtil.listCopyTo(hisMedicalRecords, MedicalRecord.class));
            if (ListUtil.isNotEmpty(hisMedicalRecordContents)) {
                medicalRecordContentServiceImpl.saveBatch(BeanUtil.listCopyTo(hisMedicalRecordContents, MedicalRecordContent.class));
            }
        } catch (Exception e) {
            Asserts.fail("文书批量插入过程出错");
        }
        return true;
    }

    /**
     * 模拟获取his某段时间的数据
     *
     * @param dataCompareVO
     * @Return java.util.List<com.lantone.daqe.dto.HisMedicalRecordDTO>
     */
    public List<HisMedicalRecordDTO> getHisMedicalRecords(DataCompareVO dataCompareVO) {
        List<HisMedicalRecordDTO> out = new ArrayList<>();
        //病历数据
        List<HisBehospitalInfo> hisBehospitalInfos = hisBehospitalInfoFacade.list(new QueryWrapper<HisBehospitalInfo>().select("behospital_code,behospital_date")
                .eq(dataCompareVO.getHospitalId() != null, "hospital_id", dataCompareVO.getHospitalId())
                .ge(dataCompareVO.getStartDate() != null && StringUtil.isBlank(dataCompareVO.getBehospitalCode()), "behospital_date", dataCompareVO.getStartDate())
                .le(dataCompareVO.getEndDate() != null && StringUtil.isBlank(dataCompareVO.getBehospitalCode()), "behospital_date", dataCompareVO.getEndDate())
                .eq(StringUtil.isNotBlank(dataCompareVO.getBehospitalCode()), "behospital_code", dataCompareVO.getBehospitalCode()));
        //通过病历获取病案首页和文书
        if (ListUtil.isEmpty(hisBehospitalInfos)) {
            return out;
        }
        List<String> codes = hisBehospitalInfos.stream().map(HisBehospitalInfo::getBehospitalCode).collect(Collectors.toList());
        //病案首页
        List<HisHomePage> homePages = hisHomePageFacade.list(new QueryWrapper<HisHomePage>().select("home_page_id,behospital_code")
                .eq(dataCompareVO.getHospitalId() != null, "hospital_id", dataCompareVO.getHospitalId())
                .in("behospital_code", codes));
        Map<String, List<HisHomePage>> homePageMap = EntityUtil.makeEntityListMap(homePages, "behospitalCode");

        //文书
        List<HisMedicalRecord> hisMedicalRecords = hisMedicalRecordFacade.list(new QueryWrapper<HisMedicalRecord>().select("rec_id,rec_title,behospital_code")
                .eq(dataCompareVO.getHospitalId() != null, "hospital_id", dataCompareVO.getHospitalId())
                .in("behospital_code", codes) );
        Map<String, List<HisMedicalRecord>> medicalRecordMap = EntityUtil.makeEntityListMap(hisMedicalRecords, "behospitalCode");

        //拼装
        hisBehospitalInfos.stream().forEach(hisBehospitalInfo -> {
            HisMedicalRecordDTO oneData = new HisMedicalRecordDTO();
            oneData.setBehospitalCode(hisBehospitalInfo.getBehospitalCode());
            oneData.setBehospitalDate(hisBehospitalInfo.getBehospitalDate());
            if (homePageMap != null && ListUtil.isNotEmpty(homePageMap.get(hisBehospitalInfo.getBehospitalCode()))) {
                oneData.setHomePageId(homePageMap.get(hisBehospitalInfo.getBehospitalCode()).get(0).getHomePageId());
            }
            List<HisRecDTO> recs = new ArrayList<>();
            if (medicalRecordMap != null && ListUtil.isNotEmpty(medicalRecordMap.get(hisBehospitalInfo.getBehospitalCode()))) {
                medicalRecordMap.get(hisBehospitalInfo.getBehospitalCode()).stream().forEach(hisMedicalRecord -> {
                    HisRecDTO rec = new HisRecDTO();
                    rec.setRecId(hisMedicalRecord.getRecId());
                    rec.setRecTitle(hisMedicalRecord.getRecTitle());
                    recs.add(rec);
                });
                oneData.setHisRecs(recs);
            }
            out.add(oneData);
        });
        return out;
    }
}