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

import cn.hutool.core.util.NumberUtil;
import com.docus.core.util.DateUtil;
import com.docus.core.util.Func;
import com.docus.core.util.ObjectUtil;
import com.docus.infrastructure.redis.service.IdService;
import com.docus.server.collection.dto.TBasicDto;
import com.docus.server.collection.httpservices.HttpTBasicService;
import com.docus.server.collection.infrastructure.dao.entity.TBasic;
import com.docus.server.collection.infrastructure.dao.mapper.TBasicMapper;
import com.docus.server.collection.service.ITBasicService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;
import java.time.Duration;
import java.util.*;

/**
 * @BelongsProject: docus-webservice-sdry
 * @BelongsPackage: com.docus.server.collection.service.impl
 * @Author: chierhao
 * @CreateTime: 2023-02-28  08:37
 * @Description: TODO
 * @Version: 1.0
 */
@Service
@Slf4j
public class TBasicServiceImpl implements ITBasicService {

    @Resource
    private TBasicMapper tBasicMapper;

    @Resource
    private HttpTBasicService httpTBasicService;

    @Resource
    private IdService idService;

    @Value("${TBasic.url}")
    private String url;

    @Override
    public void setTBasic() throws Exception {
        //读取配置文件
        File dir = new File(".");
        String path ="";
        path = dir.getCanonicalPath()+"\\dataConfig\\time.json";
        log.info("path:"+path);
        File  timeConfigFile= new File(path);
        InputStream inputstream =null;
        if(timeConfigFile.isFile()){
            inputstream=new FileInputStream(timeConfigFile);
        }
        byte[] bytes = IOUtils.toByteArray(inputstream);
        String timeJson = new String(bytes);
        Map<String,String> map = Func.readJson(timeJson, Map.class);
        inputstream.close();

        //获取开始时间
        String startTimeStr=map.get("startTime");
        Date startTime = Func.parseDate(startTimeStr, DateUtil.PATTERN_DATETIME);

        //获取开始时间到昨天时间间隔
        Date yesterday=DateUtil.minusDays(DateUtil.now(),1);
        Duration between = DateUtil.between(startTime, yesterday);

        //循环发送请求
        for(int i=0;i<=between.toDays(); i++){
            //开始时间
            Date beginTime=DateUtil.plusDays(startTime,i);
            String beginTimeStr = DateUtil.format(beginTime, DateUtil.PATTERN_DATETIME);

            //结束时间
            Date endTime = DateUtil.plusDays(beginTime, 1);
            String endTimeStr = DateUtil.format(endTime, DateUtil.PATTERN_DATETIME);
            //分页查询页面容量
            Integer pageSize=500;
            //分页查询当前页
            Integer pageNum=Integer.parseInt(map.get("pageNum"));
            //分页参数
            boolean pageFlag=true;

            //记录开始时间
            modifyJsonFile(timeConfigFile,"startTime",beginTimeStr);

            //分页查询
            for(;true;pageNum++){
                //设置请求头信息
                Map<String,String> headerMap =new  HashMap<>();
                headerMap.put("Content-Type","application/json");
                headerMap.put("domain","b91b0ac7-665f-4874-a282-2f5511a44263");
                headerMap.put("key","WZHBA");

                //设置请求参数
                Map<String,Object> paramMap = new HashMap<String,Object>(5);
                paramMap.put("operBeginDate",beginTimeStr);
                paramMap.put("operEndDate",endTimeStr);
                paramMap.put("pageSize",pageSize);
                paramMap.put("pageNum",pageNum);
                paramMap.put("pageFlag",pageFlag);
                List<TBasicDto> tBasicDtoList = httpTBasicService.getTBasicDto(url, headerMap, paramMap);

                //为空则跳出
                if(Func.isEmpty(tBasicDtoList)){
                    break;
                }
                //持久化对像集合转化
                List<TBasic> tBasicList=new ArrayList<TBasic>();
                for(TBasicDto tBasicDto:tBasicDtoList){
                    //判断jzh是否重复
                    Integer num = tBasicMapper.selectOne(tBasicDto.getJzh());

                    //判断是否血液净化的，是则跳过
                    if(ObjectUtil.isNotEmpty(tBasicDto.getInpatientNo())&&(tBasicDto.getInpatientNo().contains("x")||tBasicDto.getInpatientNo().contains("X"))){
                        continue;
                    }
                    //判断是否C的，是则跳过
                    if(ObjectUtil.isNotEmpty(tBasicDto.getInpatientNo())&&(tBasicDto.getInpatientNo().contains("c")||tBasicDto.getInpatientNo().contains("C"))){
                        continue;
                    }
                    String patientId = String.valueOf(idService.getDateSeq());

                    //数据类型转化，格式处理
                    Date admissDate = null;
                    if(Func.isNotEmpty(tBasicDto.getAdmissDate())){
                        admissDate=Func.parseDate(tBasicDto.getAdmissDate(), DateUtil.PATTERN_DATETIME);
                    }else {
                        continue;
                    }


                    Date disDate = null;
                    if(Func.isNotEmpty(tBasicDto.getDisDate())){
                         disDate = Func.parseDate(tBasicDto.getDisDate(), DateUtil.PATTERN_DATETIME);
                    }
                    String admissTimesStr = tBasicDto.getAdmissTimes();
                    Integer admissTimes=null;
                    if(NumberUtil.isInteger(admissTimesStr)){
                        admissTimes=Integer.parseInt(admissTimesStr);
                    }

                    String ageStr = tBasicDto.getAge();
                    Integer age=null;
                    if(Func.isNotEmpty(ageStr)){
                        ageStr =ageStr.substring(0,ageStr.length()-1);
                        if(NumberUtil.isInteger(ageStr)){
                            age=Integer.parseInt(ageStr);
                        }
                    }

                    String admissDaysStr = tBasicDto.getAdmissDays();
                    Integer admissDays=null;
                    if(NumberUtil.isInteger(admissDaysStr)){
                        admissDays=Integer.parseInt(admissDaysStr);
                    }

                    String isDeadStr = tBasicDto.getIsDead();
                    Integer isDead=0;
                    if("5".equals(isDeadStr)){
                        isDead=1;
                    }

                    String sexStr = tBasicDto.getSex();
                    String sex="";
                    String sexName="";
                    if("M".equals(sexStr)){
                        sexName="男";
                        sex="1";
                    }
                    if("F".equals(sexStr)){
                        sexName="女";
                        sex="2";
                    }

                    //组装数据
                    TBasic tBasic=new TBasic();
                    tBasic.setPatientId(patientId);
                    tBasic.setJzh(tBasicDto.getJzh());
                    tBasic.setInpatientNo(tBasicDto.getInpatientNo());
                    tBasic.setAdmissTimes(admissTimes);
                    tBasic.setAdmissDays(admissDays);
                    tBasic.setName(tBasicDto.getName());
                    tBasic.setAge(age);
                    tBasic.setSexName(sexName);
                    tBasic.setSex(sex);
                    tBasic.setIsDead(isDead);
                    tBasic.setAttendingName(tBasicDto.getAttendingName());
                    tBasic.setAttending(tBasicDto.getAttending());
                    tBasic.setIdCard(tBasicDto.getIdCard());
                    tBasic.setBedNum(tBasicDto.getBedNum());
                    tBasic.setDutyNurse(tBasicDto.getDutyNurse());
                    tBasic.setAdmissDate(admissDate);
                    tBasic.setAdmissDept(tBasicDto.getAdmissDept());
                    tBasic.setAdmissDeptName(tBasicDto.getAdmissDeptName());
                    tBasic.setDisDate(disDate);
                    tBasic.setDisDept(tBasicDto.getDisDept());
                    tBasic.setDisDeptName(tBasicDto.getDisDeptName());
                    tBasic.setCreateTime(DateUtil.now());
                    tBasic.setMotherInpatientNo(tBasicDto.getMotherInpatientNo());
                    //判断是否B开头
                    if(ObjectUtil.isNotEmpty(tBasicDto.getInpatientNo())&&(tBasicDto.getInpatientNo().contains("B")||tBasicDto.getInpatientNo().contains("b"))){
                        tBasic.setIsOther(1);
                    }else {
                        tBasic.setIsOther(0);
                    }

                    if (num>0) {
                        log.info("更新,jzh为"+tBasic.getJzh());
                        tBasicMapper.update(tBasic);
                    }else{
                        tBasicList.add(tBasic);
                    }
                    log.info("tBasic:"+tBasic.toString());
                }

                //批量插入
                if(Func.isNotEmpty(tBasicList)){
                    log.info("新增"+tBasicList.size()+"条基础数据开始");
                    tBasicMapper.insertBatch(tBasicList);
                    log.info("新增"+tBasicList.size()+"条基础数据结束");
                }

                //记录页码startTime
                modifyJsonFile(timeConfigFile,"pageNum",pageNum.toString());
            }
            //完成重置页码为1,并更新开始时间和结束时间为结束时间
            modifyJsonFile(timeConfigFile,"pageNum","1");
            modifyJsonFile(timeConfigFile,"startTime",endTimeStr);
        }

    }

    @Override
    public void setAttending() {
        List<TBasic> nullAttendingBasicList = tBasicMapper.getNullAttending();
        if (Func.isEmpty(nullAttendingBasicList)) {
            log.info(">>>>>>>>>> 本次无需同步住院医师");
            return;
        }
        log.info(">>>>>>>>>> 本次需同步住院医师 {} 个患者", nullAttendingBasicList.size());
        for (TBasic tBasic : nullAttendingBasicList) {
            String jzh = tBasic.getJzh();
            log.info(">>>>>>>>>> 同步住院医师病案号：{},住院流水号：{} 开始。", tBasic.getInpatientNo(), jzh);
            TBasicDto tBasicDto = new TBasicDto();
            tBasicDto.setJzh(jzh);
            httpTBasicService.setAttending(tBasicDto);
            String attending = tBasicDto.getAttending();
            if (Func.isBlank(attending)) {
                log.info(">>>>>>>>>> 同步住院医师病案号：{},住院流水号：{} 未查询到主管医生。", tBasic.getInpatientNo(), jzh);
                continue;
            }
            String attendingName = tBasicDto.getAttendingName();
            log.info(">>>>>>>>>> 同步住院医师病案号：{},住院流水号：{} 同步到的主管医生为 {}，{}。", tBasic.getInpatientNo(), jzh, attending, attendingName);
            tBasicMapper.updateAttending(tBasic.getPatientId(), attending, attendingName);
            log.info(">>>>>>>>>> 同步住院医师病案号：{},住院流水号：{} 成功。", tBasic.getInpatientNo(), jzh);
        }


    }

    public void modifyJsonFile(File file, String key, String value) {
        StringBuilder sb = new StringBuilder();
        //记录替换所在的行
        int rowLine = 0;
        //换行符
        String enter = System.getProperty("line.separator");
        PrintWriter pw = null;
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            String line;
            for (line = br.readLine(); line != null; line = br.readLine()) {
                rowLine++;
                if (line.contains(key)) {
                    String str1=line.substring(0,line.indexOf(key));
                    String str2=line.substring(line.indexOf(key));
                    String str3=str2.substring(0,str2.indexOf(":")+2);
                    String str4=str2.substring(str2.indexOf(":")+2);
                    String str5=str4.substring(str4.indexOf("\""));
                    line=str1+str3+value+str5;
                }
                //数据暂存在 StringBuilder 中
                if (rowLine == 1) {
                    sb.append(line);
                } else {
                    sb.append(enter).append(line);
                }
            }
            pw = new PrintWriter(new FileWriter(file));
            pw.print(sb);
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (pw != null) {
                pw.close();
            }
        }
    }
}


