package com.diagbot.facade;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diagbot.client.TranServiceClient;
import com.diagbot.dto.EMRIntroduceDetailDTO;
import com.diagbot.dto.GetInquiryDetailDTO;
import com.diagbot.dto.GetLastOtherDTO;
import com.diagbot.dto.HisInquiryDTO;
import com.diagbot.dto.HisInquirysForDjDTO;
import com.diagbot.dto.HospitalInfoDTO;
import com.diagbot.dto.PatientInfoDTO;
import com.diagbot.dto.ReadInquiryDTO;
import com.diagbot.dto.SaveInquiryDTO;
import com.diagbot.entity.DoctorInfo;
import com.diagbot.entity.HospitalDept;
import com.diagbot.entity.InquiryDetail;
import com.diagbot.entity.InquiryInfo;
import com.diagbot.entity.PatientInfo;
import com.diagbot.enums.IsDeleteEnum;
import com.diagbot.enums.SexTypeEnum;
import com.diagbot.service.impl.InquiryInfoServiceImpl;
import com.diagbot.util.BeanUtil;
import com.diagbot.util.DateUtil;
import com.diagbot.util.ListUtil;
import com.diagbot.util.StringUtil;
import com.diagbot.vo.GetInquiryDetailVO;
import com.diagbot.vo.GetLastOtherVO;
import com.diagbot.vo.HisInquirysForDjVO;
import com.diagbot.vo.HisInquirysVO;
import com.diagbot.vo.PatientInfoVO;
import com.diagbot.vo.ReadInquiryVO;
import com.diagbot.vo.SaveInquiryDetailVO;
import com.diagbot.vo.SaveInquiryToHisVO;
import com.diagbot.vo.SaveInquiryVO;

/**
 * @author rengb
 * @Description
 * @time 2018年11月23日下午2:08:08
 */
@Component
public class InquiryInfoFacade extends InquiryInfoServiceImpl {

    @Autowired
    private InquiryDetailFacade inquiryDetailFacade;
    @Autowired
    private HospitalInfoFacade hospitalInfoFacade;
    @Autowired
    private PatientInfoFacade patientInfoFacade;
    @Autowired
    private DoctorInfoFacade doctorInfoFacade;
    @Autowired
    private HospitalDeptFacade hospitalDeptFacade;
    @Autowired
    private TranServiceClient tranServiceClient;

    /**
     * 问诊记录保存
     *
     * @param saveInquiryVO
     * @return
     */
    @Transactional
    public SaveInquiryDTO saveInquiry(SaveInquiryVO saveInquiryVO) {
        SaveInquiryDTO saveInquiryDTO = new SaveInquiryDTO();
        Date now = new Date();

        QueryWrapper<InquiryInfo> queryWrapper = new QueryWrapper<InquiryInfo>();
        queryWrapper.eq("is_deleted", IsDeleteEnum.N.getKey());
        queryWrapper.eq("hospital_id", saveInquiryVO.getHospitalId());
        queryWrapper.eq("hospital_dept_id", saveInquiryVO.getHospitalDeptId());
        queryWrapper.eq("doctor_id", saveInquiryVO.getDoctorId());
        queryWrapper.eq("patient_id", saveInquiryVO.getPatientId());
        queryWrapper.eq("inquiry_code", saveInquiryVO.getInquiryCode());
        InquiryInfo inquiryInfo = this.getOne(queryWrapper);

        Long inquiryId = null;
        InquiryInfo inquiryInfoSave = new InquiryInfo();
        inquiryInfoSave.setHospitalId(saveInquiryVO.getHospitalId());
        inquiryInfoSave.setHospitalDeptId(saveInquiryVO.getHospitalDeptId());
        inquiryInfoSave.setDoctorId(saveInquiryVO.getDoctorId());
        inquiryInfoSave.setPatientId(saveInquiryVO.getPatientId());
        inquiryInfoSave.setInquiryCode(saveInquiryVO.getInquiryCode());
        inquiryInfoSave.setRegVisitedState(saveInquiryVO.getRegVisitedState());
        inquiryInfoSave.setType(saveInquiryVO.getType());
        inquiryInfoSave.setDiagnose(saveInquiryVO.getDiagnose());
        inquiryInfoSave.setSign(saveInquiryVO.getSign());
        inquiryInfoSave.setDataJson(saveInquiryVO.getDataJson());
        if (inquiryInfo == null) {
            inquiryInfoSave.setGmtCreate(now);
            inquiryInfoSave.setGmtModified(now);
            this.save(inquiryInfoSave);
            inquiryId = inquiryInfoSave.getId();
        } else {
            inquiryId = inquiryInfo.getId();
            inquiryInfoSave.setId(inquiryId);
            inquiryInfoSave.setGmtModified(now);
            this.updateById(inquiryInfoSave);

            inquiryDetailFacade.removeByInquiryId(inquiryId);
        }

        List<InquiryDetail> inquiryDetailList = new ArrayList<>();
        List<String> contentList = new ArrayList<>();
        for (SaveInquiryDetailVO i : saveInquiryVO.getDetailList()) {
            InquiryDetail inquiryDetail = new InquiryDetail();
            inquiryDetail.setInquiryId(inquiryId);
            inquiryDetail.setType(i.getType());
            inquiryDetail.setContent(i.getContent());
            inquiryDetail.setContentValue(i.getContentValue());
            inquiryDetail.setGmtCreate(now);
            inquiryDetailList.add(inquiryDetail);
            contentList.add(i.getContentValue());
        }
        if (inquiryDetailList.size() > 0) {
            inquiryDetailFacade.saveInquiryDetails(inquiryDetailList);
        }

        saveInquiryDTO.setInquiryId(inquiryId);
        
        SaveInquiryToHisVO saveInquiryToHisVO = new SaveInquiryToHisVO();
        saveInquiryToHisVO.setContentList(contentList);
        tranServiceClient.saveInquiryToHis(saveInquiryToHisVO);
        
        return saveInquiryDTO;
    }

    /**
     * 问诊记录回显
     *
     * @param readInquiryVO
     * @return
     */
    public ReadInquiryDTO readInquiry(ReadInquiryVO readInquiryVO) {
        ReadInquiryDTO readInquiryDTO = new ReadInquiryDTO();
        QueryWrapper<InquiryInfo> queryWrapper = new QueryWrapper<InquiryInfo>();
        queryWrapper.eq("is_deleted", IsDeleteEnum.N.getKey());
        queryWrapper.eq("hospital_id", readInquiryVO.getHospitalId());
        queryWrapper.eq("hospital_dept_id", readInquiryVO.getHospitalDeptId());
        queryWrapper.eq("doctor_id", readInquiryVO.getDoctorId());
        queryWrapper.eq("patient_id", readInquiryVO.getPatientId());
        queryWrapper.eq("inquiry_code", readInquiryVO.getInquiryCode());
        InquiryInfo inquiryInfo = this.getOne(queryWrapper);

        if (inquiryInfo != null) {
            readInquiryDTO.setDataJson(inquiryInfo.getDataJson());
            BeanUtil.copyProperties(inquiryInfo, readInquiryDTO);
            
            QueryWrapper<InquiryDetail> inquiryDetailQe = new QueryWrapper<>();
            inquiryDetailQe.eq("inquiry_id", inquiryInfo.getId());
            readInquiryDTO.setDetailList(inquiryDetailFacade.list(inquiryDetailQe).stream().sorted((a,b)->a.getType()-b.getType()).collect(Collectors.toList()));
        }

        return readInquiryDTO;
    }

    /**
     * 获取最近一次其他史信息
     *
     * @param getLastOtherVO
     * @return
     */
    public GetLastOtherDTO getLastOther(GetLastOtherVO getLastOtherVO) {
    	GetLastOtherDTO getLastOtherDTO = new GetLastOtherDTO();
    	
    	HospitalInfoDTO hospitalInfoDTO = hospitalInfoFacade.getHospitalByCode(getLastOtherVO.getHospitalCode());
    	
    	PatientInfoVO patientInfoVO = new PatientInfoVO();
    	patientInfoVO.setHospitalCode(getLastOtherVO.getHospitalCode());
    	patientInfoVO.setPatientCode(getLastOtherVO.getPatientCode());
    	PatientInfoDTO patientInfoDTO = patientInfoFacade.getPatientInfo(patientInfoVO);

        Map<String, Object> map = new HashMap<>();
        map.put("hospitalId", hospitalInfoDTO.getId());
        map.put("patientId", patientInfoDTO.getId());
        map.put("sign", getLastOtherVO.getSign());
        InquiryInfo inquiryInfo = baseMapper.getPatientLast(map);

        if (inquiryInfo != null) {
        	getLastOtherDTO.setDataJson(inquiryInfo.getDataJson());
        	
        	QueryWrapper<InquiryDetail> inquiryDetailQe = new QueryWrapper<>();
            inquiryDetailQe.eq("inquiry_id", inquiryInfo.getId());
            inquiryDetailQe.eq("type", 3);
            InquiryDetail inquiryDetail = inquiryDetailFacade.getOne(inquiryDetailQe);
            if(inquiryDetail!=null){
            	getLastOtherDTO.setOtherStr(inquiryDetail.getContent());
            }
        }
        return getLastOtherDTO;
    }

    /**
     * 历史病历列表
     *
     * @param hisInquirysVO
     * @return
     */
    public List<HisInquiryDTO> hisInquirys(HisInquirysVO hisInquirysVO) {
        QueryWrapper<InquiryInfo> queryWrapper = new QueryWrapper<InquiryInfo>();
        queryWrapper.eq("is_deleted", IsDeleteEnum.N.getKey());
        queryWrapper.eq("hospital_id", hisInquirysVO.getHospitalId());
        if(hisInquirysVO.getHospitalDeptId()!=null){
        	queryWrapper.eq("hospital_dept_id", hisInquirysVO.getHospitalDeptId());
        }
        if(hisInquirysVO.getDoctorId()!=null){
        	queryWrapper.eq("doctor_id", hisInquirysVO.getDoctorId());
        }
        if (hisInquirysVO.getPatientId() != null) {
            queryWrapper.eq("patient_id", hisInquirysVO.getPatientId());
        }
        if (hisInquirysVO.getType() != null) {
            queryWrapper.eq("type", hisInquirysVO.getType());
        }
        if (hisInquirysVO.getSign() != null) {
            queryWrapper.eq("sign", hisInquirysVO.getSign());
        }
        if (hisInquirysVO.getStartDate() != null) {
            queryWrapper.ge("gmt_create", hisInquirysVO.getStartDate());
        }
        if (hisInquirysVO.getEndDate() != null) {
            queryWrapper.le("gmt_create", hisInquirysVO.getEndDate());
        }
        if (hisInquirysVO.getOrderType() == 1) {
            queryWrapper.orderByDesc("gmt_modified");
        } else if (hisInquirysVO.getOrderType() == 2) {
            queryWrapper.orderByAsc("gmt_modified");
        }
        List<InquiryInfo> inquiryInfoList = this.list(queryWrapper);
        if (inquiryInfoList.size() == 0) {
            return null;
        }

        List<Long> hospitalDeptIdList = inquiryInfoList.stream().map(i -> i.getHospitalDeptId()).collect(Collectors.toList());
        List<Long> doctorIdList = inquiryInfoList.stream().map(i -> i.getDoctorId()).collect(Collectors.toList());
        List<Long> patientIdList = inquiryInfoList.stream().map(i -> i.getPatientId()).collect(Collectors.toList());
        List<Long> inquiryIdList = inquiryInfoList.stream().map(i -> i.getId()).collect(Collectors.toList());

        Map<Long, HospitalDept> hospitalDeptMap = hospitalDeptFacade.hospitalDeptInfoMapByIds(hospitalDeptIdList);
        Map<Long, DoctorInfo> doctorInfoMap = doctorInfoFacade.doctorInfoMapByIds(doctorIdList);
        Map<Long, PatientInfo> patientInfoMap = patientInfoFacade.patientInfoMapByIds(patientIdList);
        Map<Long, List<InquiryDetail>> inquiryDetailMap = inquiryDetailFacade.getDetailsByInquryIds(inquiryIdList);

        List<HisInquiryDTO> hisInquiryDTOList = new ArrayList<>();
        inquiryInfoList.forEach(i -> {
            HisInquiryDTO hisInquiryDTO = new HisInquiryDTO();
            BeanUtil.copyProperties(i, hisInquiryDTO);
            hisInquiryDTO.setInquiryDate(i.getGmtModified());
            hisInquiryDTO.setInquiryTime(i.getGmtModified());
            hisInquiryDTO.setHospitalDeptName(Optional.ofNullable(hospitalDeptMap.get(i.getHospitalDeptId())).map(t -> t.getName()).orElse(null));
            hisInquiryDTO.setDoctorName(Optional.ofNullable(doctorInfoMap.get(i.getDoctorId())).map(t -> t.getName()).orElse(null));
            PatientInfo patientInfo = patientInfoMap.get(i.getPatientId());
            if (patientInfo != null) {
                hisInquiryDTO.setPatientName(patientInfo.getName());
                hisInquiryDTO.setPatientIdNo(patientInfo.getIdNo());
                hisInquiryDTO.setPatientSex(SexTypeEnum.getName(patientInfo.getSex()));
                hisInquiryDTO.setPatientAge(DateUtil.yearCompare(patientInfo.getBirthday(), DateUtil.now()));
            }

            hisInquiryDTO.setDetailList(inquiryDetailMap.get(i.getId()));
            hisInquiryDTOList.add(hisInquiryDTO);
        });


        return hisInquiryDTOList;
    }
    
    /**
     * 对接-历史病历列表
     *
     * @param hisInquirysForDjVO
     * @return
     */
    public List<HisInquirysForDjDTO> hisInquirysForDj(HisInquirysForDjVO hisInquirysForDjVO) {
    	QueryWrapper<InquiryInfo> queryWrapper = new QueryWrapper<InquiryInfo>();
        queryWrapper.eq("is_deleted", IsDeleteEnum.N.getKey());
        queryWrapper.eq("hospital_id", hisInquirysForDjVO.getHospitalId());
        if(hisInquirysForDjVO.getHospitalDeptId()!=null){
        	queryWrapper.eq("hospital_dept_id", hisInquirysForDjVO.getHospitalDeptId());
        }
        if(hisInquirysForDjVO.getDoctorId()!=null){
        	queryWrapper.eq("doctor_id", hisInquirysForDjVO.getDoctorId());
        }
        if (hisInquirysForDjVO.getPatientId() != null) {
            queryWrapper.eq("patient_id", hisInquirysForDjVO.getPatientId());
        }
        if(StringUtil.isNotBlank(hisInquirysForDjVO.getInquiryCode())){
        	queryWrapper.eq("inquiry_code", hisInquirysForDjVO.getInquiryCode());
        }
        if (hisInquirysForDjVO.getType() != null) {
            queryWrapper.eq("type", hisInquirysForDjVO.getType());
        }
        if (hisInquirysForDjVO.getSign() != null) {
            queryWrapper.eq("sign", hisInquirysForDjVO.getSign());
        }
        if (hisInquirysForDjVO.getStartDate() != null) {
            queryWrapper.ge("gmt_create", hisInquirysForDjVO.getStartDate());
        }
        if (hisInquirysForDjVO.getEndDate() != null) {
            queryWrapper.le("gmt_create", hisInquirysForDjVO.getEndDate());
        }
        if (hisInquirysForDjVO.getOrderType() == 1) {
            queryWrapper.orderByDesc("gmt_modified");
        } else if (hisInquirysForDjVO.getOrderType() == 2) {
            queryWrapper.orderByAsc("gmt_modified");
        }
        List<InquiryInfo> inquiryInfoList = this.list(queryWrapper);
        if (ListUtil.isEmpty(inquiryInfoList)) {
            return null;
        }
        
        Map<Long, List<InquiryDetail>> inquiryDetailMap = inquiryDetailFacade.getDetailsByInquryIds(inquiryInfoList.stream().map(i -> i.getId()).collect(Collectors.toList()));
        List<HisInquirysForDjDTO> hisInquirysForDjDTOList = BeanUtil.listCopyTo(inquiryInfoList, HisInquirysForDjDTO.class);
        
        hisInquirysForDjDTOList.forEach(i->{
        	i.setContentList(inquiryDetailMap.get(i.getId()).stream().map(k->k.getContentValue()).collect(Collectors.toList()));
        });
        
        return hisInquirysForDjDTOList;
    }
    

    /**
     * 病历详情
     *
     * @param getInquiryDetailVO
     * @return
     */
    public GetInquiryDetailDTO getInquiryDetail(GetInquiryDetailVO getInquiryDetailVO) {
        GetInquiryDetailDTO getInquiryDetailDTO = new GetInquiryDetailDTO();

        List<InquiryDetail> inquiryDetailList = inquiryDetailFacade.getListByInquryId(getInquiryDetailVO.getInquiryId());

        getInquiryDetailDTO.setInquiryDetailList(inquiryDetailList);

        return getInquiryDetailDTO;
    }

}
