package com.docus.server.archive.job;

import com.alibaba.fastjson.JSONObject;
import com.docus.core.util.DateUtil;
import com.docus.core.util.Func;
import com.docus.infrastructure.core.utils.TableJsonRead;
import com.docus.server.archive.config.DocusProperties;
import com.docus.server.archive.constans.SyncConstant;
import com.docus.server.archive.service.PatientInfoSyncService;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 患者基础数据同步job
 *
 * @author YongBin Wen
 * @date 2024/5/27 9:16
 */
@Component
@Slf4j
public class PatientInfoSyncJob {

    @Resource
    private DocusProperties docusProperties;
    @Autowired
    private Map<String, PatientInfoSyncService> patientInfoSyncServiceMap = new ConcurrentHashMap<>();

    @XxlJob("PatientInfoSyncByModifyTimeJob")
    public void patientInfoSyncByModifyTime() {
        String syncServicePrefix = docusProperties.getSyncServicePrefix();
        log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {} 患者基础数据按照最后修改时间同步开始了!", syncServicePrefix);
        String serviceName = syncServicePrefix + SyncConstant.PATIENT_INFO_SYNC_SERVICE_SUFFIX;
        PatientInfoSyncService patientInfoSyncService = patientInfoSyncServiceMap.get(serviceName);
        if (patientInfoSyncService == null) {
            log.error(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  患者基础数据同步服务 {} 未找到!", serviceName);
            return;
        }
        String jobConfigPath = "data-config\\job-config";
        String jobConfigName = "ViewPatientInfoSyncJob.json";
        TableJsonRead jsonReader = new TableJsonRead();
        PatientInfoSyncJobConfig syncJobConfig = jsonReader.Read(jobConfigPath, jobConfigName, PatientInfoSyncJobConfig.class);
        syncJobConfig = PatientInfoSyncJobConfig.checkAndInit(syncJobConfig);
        String startDate = syncJobConfig.getStartDate();
        LocalDate runLocalDate = LocalDate.now();
        String startDateTimeStr = startDate + " 00:00:00";
        String endDateTimeStr = runLocalDate.toString() + " 23:59:59";
        try {
            patientInfoSyncService.syncByModifyTimeRange(Func.parseDateTime(startDateTimeStr), Func.parseDateTime(endDateTimeStr));
            log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {} 患者基础数据按照最后修改时间 {} ，{} 同步结束了!", syncServicePrefix, startDateTimeStr, endDateTimeStr);
            // 下次同步则开始多同步一天，防止时间差引起同步缺漏 例如  10分钟同步一次 导致 23:50:01 出院未同步到
            String nexRunStartDate = runLocalDate.plusDays(-1).toString();
            syncJobConfig.setStartDate(nexRunStartDate);
            jsonReader.Save(jobConfigPath, jobConfigName, Func.toJson(syncJobConfig));
        } catch (Exception ex) {
            log.error(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> " + syncServicePrefix + " 患者基础数据按照最后修改时间 " + startDateTimeStr + "," + endDateTimeStr + " 出现异常!" + ex.getMessage(), ex);
        }

    }


    @XxlJob("MzsyPatientInfoSyncByModifyTimeJob")
    public void mzsyPatientInfoSyncByModifyTimeJob() {
        String syncServicePrefix = docusProperties.getSyncServicePrefix();
        log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {} 患者基础数据按照最后修改时间同步开始了!", syncServicePrefix);
        String serviceName = syncServicePrefix + SyncConstant.PATIENT_INFO_SYNC_SERVICE_SUFFIX;
        PatientInfoSyncService patientInfoSyncService = patientInfoSyncServiceMap.get(serviceName);
        if (patientInfoSyncService == null) {
            log.error(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  患者基础数据同步服务 {} 未找到!", serviceName);
            return;
        }
        String jobConfigPath = "data-config\\job-config";
        String jobConfigName = "ViewPatientInfoSyncJob.json";
        TableJsonRead jsonReader = new TableJsonRead();
        PatientInfoSyncJobConfig syncJobConfig = jsonReader.Read(jobConfigPath, jobConfigName, PatientInfoSyncJobConfig.class);
        syncJobConfig = PatientInfoSyncJobConfig.checkAndInit(syncJobConfig);
        String cyrqStart = syncJobConfig.getCyrqStart();
        String startTime = syncJobConfig.getStartTime();
        String now = DateUtil.format(DateUtil.now(), DateUtil.PATTERN_DATETIME);
        try {
            patientInfoSyncService.syncByModifyTimeAndCyrq(cyrqStart, startTime);
            log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {} 患者基础数据按照最后修改时间 {} 同步结束了!", syncServicePrefix, startTime);
            syncJobConfig.setStartTime(now);
            jsonReader.Save(jobConfigPath, jobConfigName, Func.toJson(syncJobConfig));
        } catch (Exception ex) {
            log.error(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> " + syncServicePrefix + " 患者基础数据按照最后修改时间 " + startTime + " 出现异常!" + ex.getMessage(), ex);
        }

    }

    /**
     * 广州中西医结合医院质控患者信息同步job
     *
     * @date 2024/8/23 10:21
     * @author YongBin Wen
     */
    @XxlJob("GzZxyJhQcPatientInfoSyncJob")
    public void gzZxyJhQcPatientInfoSyncJob() {
        String syncServicePrefix = "gzzxyjhqc";
        log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {} 患者基础数据按照出院日期，ws接口同步开始了!", syncServicePrefix);
        String serviceName = syncServicePrefix + SyncConstant.PATIENT_INFO_SYNC_SERVICE_SUFFIX;
        PatientInfoSyncService patientInfoSyncService = patientInfoSyncServiceMap.get(serviceName);
        if (patientInfoSyncService == null) {
            log.error(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  患者基础数据同步服务 {} 未找到!", serviceName);
            return;
        }

        String jobConfigPath = "data-config\\job-config";
        String jobConfigName = "GzZxyJhQcPatientInfoSyncJob.json";
        TableJsonRead jsonReader = new TableJsonRead();
        JSONObject syncJobConfig = jsonReader.Read(jobConfigPath, jobConfigName, JSONObject.class);
        String startDateStr = syncJobConfig.getString("startDate");
        // 出院日期存在误差天数，因为不是按照修改时间
        int errorDays = syncJobConfig.getIntValue("errorDays");
        LocalDate startDate = Func.parseDate(startDateStr);
        LocalDate endDate = LocalDate.now();
        try {
            patientInfoSyncService.syncByDisDateRange(startDate, endDate);
            log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {} 患者基础数据按照出院日期 {} 开始，同步结束了!", syncServicePrefix, startDateStr);
            syncJobConfig.put("startDate", endDate.plusDays(-errorDays).toString());
            jsonReader.Save(jobConfigPath, jobConfigName, Func.toJson(syncJobConfig));
        } catch (Exception ex) {
            log.error(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> " + syncServicePrefix + " 患者基础数据按照出院日期 " + startDateStr + " 出现异常!" + ex.getMessage(), ex);
        }


    }


    private static class PatientInfoSyncJobConfig {
        private String startDate;
        private String startTime;
        private String cyrqStart;


        public static PatientInfoSyncJobConfig checkAndInit(PatientInfoSyncJobConfig jobConfig) {
            if (Objects.isNull(jobConfig)) {
                jobConfig = new PatientInfoSyncJobConfig();
            }
            if (Objects.isNull(jobConfig.getStartDate())) {
                jobConfig.setStartDate(LocalDate.now().toString());
            }
            return jobConfig;
        }

        public String getStartDate() {
            return startDate;
        }

        public void setStartDate(String startDate) {
            this.startDate = startDate;
        }

        public String getStartTime() {
            return startTime;
        }

        public void setStartTime(String startTime) {
            this.startTime = startTime;
        }

        public String getCyrqStart() {
            return cyrqStart;
        }
    }
}
