package com.diagbot.facade.data;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.diagbot.dto.AnalyzeRunDTO;
import com.diagbot.dto.RespDTO;
import com.diagbot.dto.data.AHomePageDTO;
import com.diagbot.entity.HomePage;
import com.diagbot.enums.IsDeleteEnum;
import com.diagbot.facade.BehospitalInfoFacade;
import com.diagbot.service.impl.HomePageServiceImpl;
import com.diagbot.util.*;
import com.diagbot.vo.AnalyzeRunVO;
import com.diagbot.vo.data.*;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class AHomePageFacade extends HomePageServiceImpl{

    @Autowired
    @Qualifier("homePageServiceImpl")
    private HomePageServiceImpl homePageService;

    @Autowired
    private AHomeDiagnoseInfoFacade aHomeDiagnoseInfoFacade;

    @Autowired
    private AHomeOperationInfoFacade aHomeOperationInfoFacade;

    @Autowired
    private BehospitalInfoFacade behospitalInfoFacade;

    @Autowired
    private ReadProperties readProperties;

    @Autowired
    private AMedAbnormalInfoFacade aMedAbnormalInfoFacade;

    @Value("${log_switch.enable}")
    private boolean logSwitch;

    private TZDBConn tzDBConn = new TZDBConn();

    /**
     * 同步前一天病案首页
     */
    public void executeHomePage() {
        //String sql="select * from br_rechome where cjcxrq>=dateadd(day,-2,getdate()) and cjcxrq<=getdate()";
        //同步前一天的数据
        String sql="select * from br_rechome where cjcxrq>=(select CONVERT(varchar,GETDATE()-2,23)) and cjcxrq<(select CONVERT(varchar,GETDATE(),23))";
        List<HomePage> homePageList = tzDBConn.getHomePage(sql);
        /*
        int mod=Math.floorMod(homePageList.size(),500);
        int div=Math.floorDiv(homePageList.size(),500);
        for (int i = 0; i <= homePageList.size(); i++) {
            System.out.println((i-1)*500+"---"+(i*500));
            homePageList=homePageList.subList((i*500),(i+1)*500);
            execute(homePageList);
        }
        */
        execute(homePageList);
    }

    /**
     * 运行质控-验证数据有效性
     * @param aHomePageIngVO
     * @return
     */
    public RespDTO<Map<String, Object>> executeHomePageIng(AHomePageIngVO aHomePageIngVO){
        if(aHomePageIngVO.getHomePages()!=null && aHomePageIngVO.getHomePages().size()>0){
            //验证数据有效性
            for (AHomePageVO aHomePageVO:aHomePageIngVO.getHomePages()) {
                if("".equals(aHomePageVO.getHomePageId())) {
                    return RespDTO.onError("请输入病案首页编号!");
                }else if(aHomePageVO.getHospitalId()==null){
                    return RespDTO.onError("请输入医院编码!");
                }else if("".equals(aHomePageVO.getBehospitalCode())){
                    return RespDTO.onError("请输入病人住院编码!");
                }
                //出院诊断
                if(aHomePageVO.getLeaveDiags()!=null && aHomePageVO.getLeaveDiags().size()>0){
                    for (AHomeDiagnoseVO aHomeDiagnoseVO:aHomePageVO.getLeaveDiags()){
                        if("".equals(aHomeDiagnoseVO.getHomePageId())) {
                            return RespDTO.onError("出院诊断未输入病案首页编号!");
                        }else if(aHomeDiagnoseVO.getHospitalId()==null){
                            return RespDTO.onError("出院诊断未输入医院编码!");
                        }else if("".equals(aHomeDiagnoseVO.getDiagnoseOrderNo())){
                            return RespDTO.onError("出院诊断未输入顺序号!");
                        }
                    }
                };

                //住院手术
                if(aHomePageVO.getOperations()!=null && aHomePageVO.getOperations().size()>0){
                    for (AHomeOperationVO aHomeOperationVO:aHomePageVO.getOperations()){
                        if("".equals(aHomeOperationVO.getHomePageId())) {
                            return RespDTO.onError("住院手术未输入病案首页编号!");
                        }else if(aHomeOperationVO.getHospitalId()==null){
                            return RespDTO.onError("住院手术未输入医院编码!");
                        }else if("".equals(aHomeOperationVO.getOperationOrderNo())){
                            return RespDTO.onError("住院手术未输入顺序号!");
                        }
                    }
                }
            }

            //装载数据
            updateHomePageIng(aHomePageIngVO);
            //评分后返回结构体
            return homePageIng(aHomePageIngVO);
        }else{
            return RespDTO.onError("未接收到数据!");
        }
    }

    /**
     * 更新数据到数据库
     * @param aHomePageIngVO
     */
    private void updateHomePageIng(AHomePageIngVO aHomePageIngVO){
        try {
            List<HomePage> homePageList=Lists.newArrayList();
            aHomePageIngVO.getHomePages().stream().forEach(s->{
                //初始化入参
                HomePage homePage=new HomePage();
                BeanUtil.copyProperties(s,homePage);
                homePage.setBirthday(DateUtil.parseDate(s.getBirthday()));
                homePageList.add(homePage);

                //初始化诊断和手术，并同步到数据库
                aHomeDiagnoseInfoFacade.executeHomeDiagnose(s.getLeaveDiags());//首页诊断
                aHomeOperationInfoFacade.executeHomeOperation(s.getOperations());//首页手术
            });
            execute(homePageList);
        }catch (Exception e){
            log.error(e.getMessage(),e);
            aMedAbnormalInfoFacade.saveAbnormalInfo("病案首页","", JSON.toJSONString(aHomePageIngVO),"",e.getMessage());
        }
    }

    /**
     * 评分后返回结构体
     * @param aHomePageIngVO
     * @return
     */
    private RespDTO<Map<String, Object>> homePageIng(AHomePageIngVO aHomePageIngVO){
        String behospitalCode =aHomePageIngVO.getHomePages().get(0).getBehospitalCode();
        Long hospitalId=aHomePageIngVO.getHomePages().get(0).getHospitalId();
        Long modeId=Long.valueOf("6");//病案首页默认为6
        if(aHomePageIngVO.getDockModeType().equals("0")){
            Map<String,Object> map=new HashMap<String,Object>();
            List<AHomePageDTO> homePageDtoList=BeanUtil.listCopyTo(aHomePageIngVO.getHomePages(),AHomePageDTO.class);
            map.put("homePages",homePageDtoList);
            return RespDTO.onSuc(map);
        }else if(aHomePageIngVO.getDockModeType().equals("1")){
            //页面模式
            String url=readProperties.getProcessQcUrl()+"?behospitalCode="+behospitalCode+"&hospitalId="+hospitalId+"&modeId="+modeId;
            Map<String,Object> map=new HashMap<String,Object>();
            map.put("url",url);
            return RespDTO.onSuc(map);
        }else if(aHomePageIngVO.getDockModeType().equals("2")){
            AnalyzeRunVO analyzeRunVO=new AnalyzeRunVO();
            analyzeRunVO.setBehospitalCode(behospitalCode);
            analyzeRunVO.setHospitalId(hospitalId);
            analyzeRunVO.setModeId(modeId);
            AnalyzeRunDTO analyzeRunDTO=behospitalInfoFacade.analyzeRun(analyzeRunVO);
            Map<String,Object> map=new HashMap<String,Object>();
            if(analyzeRunDTO.getMsgDTOList().size()>0){
                map.put("analyze",analyzeRunDTO.getMsgDTOList());
            }
            return RespDTO.onSuc(map);
        }else{
            //页面模式+接口引擎模式
            String url=readProperties.getProcessQcUrl()+"?behospitalCode="+behospitalCode+"&hospitalId="+hospitalId+"&modeId="+modeId;

            AnalyzeRunVO analyzeRunVO=new AnalyzeRunVO();
            analyzeRunVO.setBehospitalCode(behospitalCode);
            analyzeRunVO.setHospitalId(hospitalId);
            analyzeRunVO.setModeId(modeId);
            AnalyzeRunDTO analyzeRunDTO=behospitalInfoFacade.analyzeRun(analyzeRunVO);
            Map<String,Object> map=new HashMap<String,Object>();
            if(analyzeRunDTO.getMsgDTOList().size()>0){
                map.put("url",url);
                map.put("analyze",analyzeRunDTO.getMsgDTOList());
            }
            return RespDTO.onSuc(map);
        }
    }


    /**
     * 通过接口更新病案首页-不包含医嘱和手术
     * @param list
     * @return
     */
    public RespDTO<List<AHomePageDTO>> executeHomePage(List<AHomePageVO> list) {
        if(list!=null && list.size()>0){
            //循环验证数据有效性
            for (AHomePageVO aHomePageVO:list) {
                if("".equals(aHomePageVO.getHomePageId())) {
                    return RespDTO.onError("请输入病案首页编号!");
                }else if(aHomePageVO.getHospitalId()==null){
                    return RespDTO.onError("请输入医院编码!");
                }else if("".equals(aHomePageVO.getBehospitalCode())){
                    return RespDTO.onError("请输入病人住院编码!");
                }
            }
            //装载数据
            List<HomePage> homePageList=Lists.newArrayList();
            list.stream().forEach(s->{
                //初始化入参
                HomePage homePage=new HomePage();
                BeanUtil.copyProperties(s,homePage);
                homePage.setBirthday(DateUtil.parseDate(s.getBirthday()));
                homePage.setBehospitalDate(DateUtil.parseDateTime(s.getBehospitalDate()));
                homePage.setLeaveHospitalDate(DateUtil.parseDateTime(s.getLeaveHospitalDate()));
                homePage.setQcDate(DateUtil.parseDateTime(s.getQcDate()));
                homePageList.add(homePage);
            });
            execute(homePageList);
            List<AHomePageDTO> homePageDtoList=BeanUtil.listCopyTo(list,AHomePageDTO.class);
            return RespDTO.onSuc(homePageDtoList);
        }else{
            return RespDTO.onError("未接收到数据!");
        }
    }

    /**
     * 病案首页
     * @param homePageList
     */
    public void execute(List<HomePage> homePageList){
        try {
            List<HomePage> addE = Lists.newLinkedList();
            List<HomePage> updateE = Lists.newLinkedList();
            if (homePageList != null && homePageList.size() > 0) {
                homePageList.stream().forEach(s -> {
                    HomePage homePage = this.getOne(new QueryWrapper<HomePage>()
                            .eq("home_page_id", s.getHomePageId())
                            .eq("hospital_id", s.getHospitalId())
                            .eq("behospital_code", s.getBehospitalCode()), false);
                    if (homePage != null) {
                        s.setGmtModified(new Date());
                        updateE.add(s);
                    } else {
                        s.setGmtCreate(new Date());
                        addE.add(s);
                    }
                });
            }
            if(addE.size()>0){
                homePageService.saveBatch(addE);
            }
            if(updateE.size()>0){
                homePageService.updateBatchByKey(updateE);
            }
        }catch (Exception e){
            log.error(e.getMessage(),e);
            aMedAbnormalInfoFacade.saveAbnormalInfo("病案首页","", JSON.toJSONString(homePageList),"",e.getMessage());
        }
    }

    public RespDTO deleteFlag(ADeleteFlagVO aDeleteFlagVO){
        try {
            //验证数据是否存在
            if(StringUtil.isEmpty(aDeleteFlagVO.getHomePageId())) {
                return RespDTO.onError("请输入病案首页编号!");
            }else if(aDeleteFlagVO.getHospitalId()==null){
                return RespDTO.onError("请输入医院编码!");
            }else if(StringUtil.isEmpty(aDeleteFlagVO.getBehospitalCode())){
                return RespDTO.onError("请输入病人住院编码!");
            }else {
                UpdateWrapper<HomePage> updateWrapper=new UpdateWrapper<>();
                updateWrapper.eq("home_page_id", aDeleteFlagVO.getHomePageId())
                        .eq("hospital_id", aDeleteFlagVO.getHospitalId())
                        .eq("behospital_code", aDeleteFlagVO.getBehospitalCode())
                        .eq("is_deleted", IsDeleteEnum.N)
                        .set("is_deleted",IsDeleteEnum.Y)
                        .set("gmt_modified", DateUtil.now());
                Boolean flag=update(new HomePage(),updateWrapper);
                //aMedAbnormalInfoFacade.saveAbnormalInfo("病案首页-删除",JSON.toJSONString(aDeleteFlagVO),JSON.toJSONString(RespDTO.onSuc(flag)),"操作成功!");
                return RespDTO.onSuc(flag);
            }
        }catch (Exception e){
            aMedAbnormalInfoFacade.saveAbnormalInfo("病案首页-删除","",JSON.toJSONString(aDeleteFlagVO),"",e.getMessage());
            return RespDTO.onError(e.getMessage());
        }
    }
}
