package com.xinelu.manage.service.batchsendtaskinfo.impl;

import com.alibaba.fastjson2.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.xinelu.common.config.AliYunSmsTwoConfig;
import com.xinelu.common.constant.Constants;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.core.domain.entity.SysDictData;
import com.xinelu.common.core.domain.entity.SysUser;
import com.xinelu.common.enums.*;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.BracketExtractor;
import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.common.utils.regex.RegexUtil;
import com.xinelu.manage.domain.agency.Agency;
import com.xinelu.manage.domain.batchsendtaskinfo.BatchSendTaskInfo;
import com.xinelu.manage.domain.batchsendtasklabelinfo.BatchSendTaskLabelInfo;
import com.xinelu.manage.domain.batchsendtaskrecordinfo.BatchSendTaskRecordInfo;
import com.xinelu.manage.domain.batchsendtaskvariableinfo.BatchSendTaskVariableInfo;
import com.xinelu.manage.domain.dialtime.DialTime;
import com.xinelu.manage.domain.signpatientmanageroute.SignPatientManageRoute;
import com.xinelu.manage.domain.signpatientmanageroutenode.SignPatientManageRouteNode;
import com.xinelu.manage.dto.aiob.CreateTaskDto;
import com.xinelu.manage.dto.aiob.CustomerInfoDto;
import com.xinelu.manage.dto.aiob.ImportTaskDto;
import com.xinelu.manage.dto.aiob.RetryRuleList;
import com.xinelu.manage.dto.batchsendtaskinfo.BatchSendTaskDto;
import com.xinelu.manage.dto.batchsendtaskrecordinfo.BatchSendTaskRecordDto;
import com.xinelu.manage.dto.smssend.SmsInfoDTO;
import com.xinelu.manage.mapper.agency.AgencyMapper;
import com.xinelu.manage.mapper.batchsendtaskinfo.BatchSendTaskInfoMapper;
import com.xinelu.manage.mapper.batchsendtasklabelinfo.BatchSendTaskLabelInfoMapper;
import com.xinelu.manage.mapper.batchsendtaskrecordinfo.BatchSendTaskRecordInfoMapper;
import com.xinelu.manage.mapper.batchsendtaskvariableinfo.BatchSendTaskVariableInfoMapper;
import com.xinelu.manage.mapper.patientinfoimportmain.PatientInfoImportMainMapper;
import com.xinelu.manage.mapper.scriptInfo.ScriptInfoMapper;
import com.xinelu.manage.mapper.signpatientmanageroute.SignPatientManageRouteMapper;
import com.xinelu.manage.mapper.signpatientmanageroutenode.SignPatientManageRouteNodeMapper;
import com.xinelu.manage.service.aiob.IAIOBService;
import com.xinelu.manage.service.batchsendtaskinfo.IBatchSendTaskInfoService;
import com.xinelu.system.mapper.SysUserMapper;
import com.xinelu.system.service.ISysDictTypeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 批量推送任务信息Service业务层处理
 *
 * @author zh
 * @date 2026-04-26
 */
@Slf4j
@Service
public class BatchSendTaskInfoServiceImpl implements IBatchSendTaskInfoService {
    @Resource
    private BatchSendTaskInfoMapper batchSendTaskInfoMapper;
    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private AgencyMapper agencyMapper;
    @Resource
    private SignPatientManageRouteMapper signPatientManageRouteMapper;
    @Resource
    private BatchSendTaskRecordInfoMapper batchSendTaskRecordInfoMapper;
    @Resource
    private BatchSendTaskVariableInfoMapper batchSendTaskVariableInfoMapper;
    @Resource
    private SignPatientManageRouteNodeMapper signPatientManageRouteNodeMapper;
    @Resource
    private IAIOBService aiobService;
    @Resource
    private PatientInfoImportMainMapper patientInfoImportMainMapper;
    @Resource
    private ISysDictTypeService iSysDictTypeService;
    @Resource
    private RegexUtil regexUtil;
    @Resource
    private AliYunSmsTwoConfig aliYunSmsTwoConfig;
    @Value("${aiob.callBackUrl}")
    private String callBackUrl;
    @Resource
    private BatchSendTaskLabelInfoMapper batchSendTaskLabelInfoMapper;
    @Resource
    private ScriptInfoMapper scriptInfoMapper;

    private static final String SUCCESS = "OK";

    /**
     * 查询批量推送任务信息
     *
     * @param id 批量推送任务信息主键
     * @return 批量推送任务信息
     */
    @Override
    public BatchSendTaskInfo selectBatchSendTaskInfoById(Long id) {
        return batchSendTaskInfoMapper.selectBatchSendTaskInfoById(id);
    }

    /**
     * 查询批量推送任务信息列表
     *
     * @param batchSendTaskInfo 批量推送任务信息
     * @return 批量推送任务信息
     */
    @Override
    public List<BatchSendTaskInfo> selectBatchSendTaskInfoList(BatchSendTaskDto batchSendTaskInfo) {
        List<BatchSendTaskInfo> batchSendTaskInfos = batchSendTaskInfoMapper.selectBatchSendTaskInfoList(batchSendTaskInfo);
        if (CollectionUtils.isEmpty(batchSendTaskInfos)) {
            return new ArrayList<>();
        }
        for (BatchSendTaskInfo sendTaskInfo : batchSendTaskInfos) {
            if (sendTaskInfo.getPersonnelType().equals(PersonnelTypeEnum.DISCHARGED.getCode())) {
                sendTaskInfo.setPersonnelType(PersonnelTypeEnum.DISCHARGED.getInfo());
            }
            if (sendTaskInfo.getPersonnelType().equals(PersonnelTypeEnum.OUTPATIENT.getCode())) {
                sendTaskInfo.setPersonnelType(PersonnelTypeEnum.OUTPATIENT.getInfo());
            }

            if (sendTaskInfo.getPersonnelType().equals(PersonnelTypeEnum.IN_HOSPITAL.getCode())) {
                sendTaskInfo.setPersonnelType(PersonnelTypeEnum.IN_HOSPITAL.getInfo());
            }
            if (sendTaskInfo.getPersonnelType().equals(PersonnelTypeEnum.PHYSICAL_EXAMINATION.getCode())) {
                sendTaskInfo.setPersonnelType(PersonnelTypeEnum.PHYSICAL_EXAMINATION.getInfo());
            }
        }
        return batchSendTaskInfos;
    }

    /**
     * 新增批量推送任务信息
     *
     * @param batchSendTaskInfo 批量推送任务信息
     * @return 结果
     */
    @Override
    public int insertBatchSendTaskInfo(BatchSendTaskInfo batchSendTaskInfo) {
        batchSendTaskInfo.setCreateTime(LocalDateTime.now());
        if (batchSendTaskInfo.getPersonnelType().equals(PersonnelTypeEnum.DISCHARGED.getInfo())) {
            batchSendTaskInfo.setPersonnelType(PersonnelTypeEnum.DISCHARGED.getCode());
        }
        if (batchSendTaskInfo.getPersonnelType().equals(PersonnelTypeEnum.OUTPATIENT.getInfo())) {
            batchSendTaskInfo.setPersonnelType(PersonnelTypeEnum.OUTPATIENT.getCode());
        }

        if (batchSendTaskInfo.getPersonnelType().equals(PersonnelTypeEnum.IN_HOSPITAL.getInfo())) {
            batchSendTaskInfo.setPersonnelType(PersonnelTypeEnum.IN_HOSPITAL.getCode());
        }
        if (batchSendTaskInfo.getPersonnelType().equals(PersonnelTypeEnum.PHYSICAL_EXAMINATION.getInfo())) {
            batchSendTaskInfo.setPersonnelType(PersonnelTypeEnum.PHYSICAL_EXAMINATION.getCode());
        }
        return batchSendTaskInfoMapper.insertBatchSendTaskInfo(batchSendTaskInfo);
    }

    /**
     * 修改批量推送任务信息
     *
     * @param batchSendTaskInfo 批量推送任务信息
     * @return 结果
     */
    @Override
    public int updateBatchSendTaskInfo(BatchSendTaskInfo batchSendTaskInfo) {
        return batchSendTaskInfoMapper.updateBatchSendTaskInfo(batchSendTaskInfo);
    }

    /**
     * 批量删除批量推送任务信息
     *
     * @param ids 需要删除的批量推送任务信息主键
     * @return 结果
     */
    @Override
    public int deleteBatchSendTaskInfoByIds(Long[] ids) {
        return batchSendTaskInfoMapper.deleteBatchSendTaskInfoByIds(ids);
    }

    /**
     * 删除批量推送任务信息信息
     *
     * @param id 批量推送任务信息主键
     * @return 结果
     */
    @Override
    public int deleteBatchSendTaskInfoById(Long id) {
        return batchSendTaskInfoMapper.deleteBatchSendTaskInfoById(id);
    }

    @Override
    public AjaxResult batchSendTaskUpload(List<BatchSendTaskInfo> list, Integer isDistinct, String filename, String importName) {
        if (CollectionUtils.isEmpty(list) || list.size() == 0) {
            return AjaxResult.success("导入数据列表是空!");
        }
        if (Objects.isNull(isDistinct) || isDistinct == 1) {
            list = list.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
        }
        List<BatchSendTaskInfo> collect = list.stream().filter(Objects::nonNull).filter(item -> StringUtils.isEmpty(item.getPatientName()) || StringUtils.isEmpty(item.getPatientPhone()) || StringUtils.isEmpty(item.getPersonnelType()) || Objects.isNull(item.getVisitTime())).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(collect)) {
            return AjaxResult.error("用户信息不完整，姓名、联系方式、人员类型、时间均不允许为空，请完善后重试；");
        }
        SysUser sysUser = sysUserMapper.selectUserById(SecurityUtils.getUserId());
        Agency agency = agencyMapper.selectAgencyById(sysUser.getHospitalAgencyId());
        if (Objects.isNull(agency) || StringUtils.isEmpty(agency.getNodeType())) {
            return AjaxResult.error("该账号无所属医院信息，请先配置该账号所属的医院信息！");
        }
        //流水号
        String sn = "batch_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        List<String> stringList = new ArrayList<>();
        //遍历塞值
        for (BatchSendTaskInfo batchSendTaskInfo : list) {
            batchSendTaskInfo.setSn(sn);
            batchSendTaskInfo.setHospitalAgencyId(agency.getId());
            //剔除空白字符（空格、制表符、换行符、回车等）
            if (StringUtils.isNotBlank(batchSendTaskInfo.getPatientPhone())) {
                batchSendTaskInfo.setPatientPhone(batchSendTaskInfo.getPatientPhone().replaceAll("\\s+", ""));
            }
            batchSendTaskInfo.setHospitalAgencyName(agency.getAgencyName());
            batchSendTaskInfo.setImportName(importName);
            batchSendTaskInfo.setCreateTime(LocalDateTime.now());
            batchSendTaskInfo.setCreateBy(SecurityUtils.getUsername());
            batchSendTaskInfo.setDelFlag(0);
            batchSendTaskInfo.setVisitDate(batchSendTaskInfo.getVisitTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
            if (batchSendTaskInfo.getPersonnelType().equals(PersonnelTypeEnum.DISCHARGED.getInfo())) {
                batchSendTaskInfo.setPersonnelType(PersonnelTypeEnum.DISCHARGED.getCode());
            }
            if (batchSendTaskInfo.getPersonnelType().equals(PersonnelTypeEnum.OUTPATIENT.getInfo())) {
                batchSendTaskInfo.setPersonnelType(PersonnelTypeEnum.OUTPATIENT.getCode());
            }

            if (batchSendTaskInfo.getPersonnelType().equals(PersonnelTypeEnum.IN_HOSPITAL.getInfo())) {
                batchSendTaskInfo.setPersonnelType(PersonnelTypeEnum.IN_HOSPITAL.getCode());
            }
            if (batchSendTaskInfo.getPersonnelType().equals(PersonnelTypeEnum.PHYSICAL_EXAMINATION.getInfo())) {
                batchSendTaskInfo.setPersonnelType(PersonnelTypeEnum.PHYSICAL_EXAMINATION.getCode());
            }
            if (StringUtils.isBlank(batchSendTaskInfo.getDepartmentName())) {
                batchSendTaskInfo.setDepartmentName("无");
            }
            if (StringUtils.isBlank(batchSendTaskInfo.getTeamName())) {
                batchSendTaskInfo.setTeamName("无");
            }
            //取标签
            if (StringUtils.isNotBlank(batchSendTaskInfo.getPhysicalExaminationSummary())) {
                String[] strings = BracketExtractor.extractToArray(batchSendTaskInfo.getPhysicalExaminationSummary());
                stringList.addAll(Arrays.asList(strings));
                String result = Arrays.toString(strings).replaceAll("^\\[|\\]$", "");
                batchSendTaskInfo.setPhysicalExaminationLabel(result);
                if (batchSendTaskInfo.getPhysicalExaminationSummary().length() > 999) {
                    batchSendTaskInfo.setPhysicalExaminationSummary(batchSendTaskInfo.getPhysicalExaminationSummary().substring(0, 999));
                }
            }
        }
        //处理标签
        List<BatchSendTaskLabelInfo> batchSendTaskLabelInfos = batchSendTaskLabelInfoMapper.selectBatchSendTaskLabelInfoList(null);
        List<String> data = batchSendTaskLabelInfos.stream().filter(Objects::nonNull).map(BatchSendTaskLabelInfo::getPhysicalExaminationLabel).collect(Collectors.toList());
        List<String> collect1 = stringList.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
        List<String> subtract = ListUtils.subtract(collect1, data);
        if (CollectionUtils.isNotEmpty(subtract)) {
            batchSendTaskLabelInfoMapper.insertBatchSendTaskLabelInfList(subtract);
        }
        batchSendTaskInfoMapper.insertBatchSendTaskInfoList(list);
        return AjaxResult.success();
    }

    /**
     * 创建批量推送任务
     *
     * @param batchSendTaskRecordDto 任务信息
     * @return AjaxResult
     * @throws ClientException
     */
    @Override
    public AjaxResult batchSend(BatchSendTaskRecordDto batchSendTaskRecordDto) throws ClientException, IllegalAccessException {
        log.info("开始创建批量推送任务---------------");
        if (CollectionUtils.isEmpty(batchSendTaskRecordDto.getList())) {
            return AjaxResult.success();
        }
        int start = batchSendTaskRecordDto.getList().size();
        batchSendTaskRecordDto.setList(new ArrayList<>(batchSendTaskRecordDto.getList().stream()
                .filter(Objects::nonNull)
                .filter(item -> StringUtils.isNotEmpty(item.getPatientName())
                        && StringUtils.isNotEmpty(item.getPatientPhone()))
                .collect(Collectors.toMap(
                        BatchSendTaskInfo::getPatientPhone,  // 按手机号去重，也可按其他字段
                        Function.identity(),
                        (existing, replacement) -> existing.getId() > replacement.getId() ? existing : replacement
                ))
                .values()));
        int end = batchSendTaskRecordDto.getList().size();
        //新增批量推送任务记录
        BatchSendTaskRecordInfo batchSendTaskRecordInfo = new BatchSendTaskRecordInfo();
        batchSendTaskRecordInfo.setBatchTaskName(batchSendTaskRecordDto.getManageRouteName());
        //新增批量推送任务记录编号 上传平台数据的任务名称
        String batchTaskNumber = null;
        if (batchSendTaskRecordDto.getBatchTaskSource().equals(BillSourceEnum.MESSAGE.getInfo())) {
            batchTaskNumber = "hkqdermyy_message_batch" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
            batchSendTaskRecordInfo.setTemplateId(batchSendTaskRecordDto.getMessageTemplateId().toString());
            batchSendTaskRecordInfo.setTemplateName(batchSendTaskRecordDto.getMessageTemplateName());
            batchSendTaskRecordInfo.setRobotPublishId(batchSendTaskRecordDto.getMessageTemplateCode());
        }
        if (batchSendTaskRecordDto.getBatchTaskSource().equals(BillSourceEnum.TELEPHONE.getInfo())) {
            batchTaskNumber = "hkqdermyy_phone_batch" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
            batchSendTaskRecordInfo.setTemplateId(batchSendTaskRecordDto.getPhoneTemplateId());
            batchSendTaskRecordInfo.setTemplateName(batchSendTaskRecordDto.getPhoneTemplateName());
            batchSendTaskRecordInfo.setRobotPublishId(batchSendTaskRecordDto.getRobotPublishId());
        }
        batchSendTaskRecordInfo.setNodeExecuteStatus(NodeExecuteStatusEnum.EXECUTING.getInfo());
        batchSendTaskRecordInfo.setBatchTaskNumber(batchTaskNumber);
        batchSendTaskRecordInfo.setTaskExecuteType(TaskExcuteTypeEnum.BATCH_TASK.getInfo());
        batchSendTaskRecordInfo.setNodePlanTime(batchSendTaskRecordDto.getNodePlanTime());
        batchSendTaskRecordInfo.setCreateBy(SecurityUtils.getUsername());
        batchSendTaskRecordInfo.setBatchTaskSource(batchSendTaskRecordDto.getBatchTaskSource());
        batchSendTaskRecordInfo.setCreateTime(LocalDateTime.now());
        batchSendTaskRecordInfo.setPhysicalExaminationLabel(batchSendTaskRecordDto.getPhysicalExaminationLabel());
        batchSendTaskRecordInfo.setDelFlag(0);
        //保存短信变量
        List<BatchSendTaskVariableInfo> batchSendTaskVariableInfos = new ArrayList<>();
        if (Objects.nonNull(batchSendTaskRecordDto.getVars()) && batchSendTaskRecordDto.getBatchTaskSource().equals(BillSourceEnum.MESSAGE.getInfo())) {
            Set<String> keys = batchSendTaskRecordDto.getVars().keySet();
            for (String key : keys) {
                BatchSendTaskVariableInfo batchSendTaskVariableInfo = new BatchSendTaskVariableInfo();
                batchSendTaskVariableInfo.setBatchSendTaskRecordId(batchSendTaskRecordInfo.getId());
                batchSendTaskVariableInfo.setVariable(key);
                batchSendTaskVariableInfo.setVariableAttribute(batchSendTaskRecordDto.getVars().get(key));
                batchSendTaskVariableInfo.setCreateBy(SecurityUtils.getUsername());
                batchSendTaskRecordInfo.setCreateTime(LocalDateTime.now());
                batchSendTaskVariableInfos.add(batchSendTaskVariableInfo);
                batchSendTaskRecordDto.setMessageNodeContent(batchSendTaskRecordDto.getMessageNodeContent().replace("${ " + key + "}", batchSendTaskRecordDto.getVars().get(key)));
                batchSendTaskRecordInfo.setNodeContent(batchSendTaskRecordDto.getMessageNodeContent());
            }
        }
        int insertBatchSendTaskRecord = batchSendTaskRecordInfoMapper.insertBatchSendTaskRecordInfo(batchSendTaskRecordInfo);
        if (insertBatchSendTaskRecord <= 0) {
            log.info("新增批量推送任务记录失败");
            return AjaxResult.error("上传任务失败！请联系管理员！");
        }
        List<SignPatientManageRoute> signPatientManageRoutes = new ArrayList<>();
        List<SignPatientManageRouteNode> signPatientManageRouteNodes = new ArrayList<>();
        String[] keys = new String[0];
        if (batchSendTaskRecordDto.getBatchTaskSource().equals(BillSourceEnum.TELEPHONE.getInfo())) {
            String s1 = scriptInfoMapper.selectVariablesByRobotPublishId(batchSendTaskRecordDto.getRobotPublishId());
            keys = s1.split("\\|");
        }
        for (BatchSendTaskInfo batchSendTaskInfo : batchSendTaskRecordDto.getList()) {
            //节点主表
            SignPatientManageRoute signPatientManageRoute = new SignPatientManageRoute();
            signPatientManageRoute.setRouteName(batchSendTaskRecordDto.getManageRouteName());
            signPatientManageRoute.setTaskCreateType(TaskCreateTypeEnum.MANUAL_CREATE.getInfo());
            signPatientManageRoute.setCreateBy(SecurityUtils.getUsername());
            signPatientManageRoute.setCreateTime(LocalDateTime.now());
            signPatientManageRoute.setTaskExcuteType(TaskExcuteTypeEnum.BATCH_TASK.getInfo());
            signPatientManageRoute.setPatientName(batchSendTaskInfo.getPatientName());
            signPatientManageRoute.setBatchSendTaskRecordId(batchSendTaskRecordInfo.getId());
            signPatientManageRoute.setBatchSendTaskId(batchSendTaskInfo.getId());
            signPatientManageRoutes.add(signPatientManageRoute);
            //节点node表
            SignPatientManageRouteNode signPatientManageRouteNode = new SignPatientManageRouteNode();
            signPatientManageRouteNode.setManageRouteName(batchSendTaskRecordDto.getManageRouteName());
            signPatientManageRouteNode.setSn(batchTaskNumber);
            signPatientManageRouteNode.setTaskExcuteType(TaskExcuteTypeEnum.BATCH_TASK.getInfo());
            signPatientManageRouteNode.setNodePlanTime(batchSendTaskRecordDto.getNodePlanTime());
            if (batchSendTaskRecordDto.getBatchTaskSource().equals(BillSourceEnum.TELEPHONE.getInfo())) {
                signPatientManageRouteNode.setDialStatus(DialStatusEnum.NODIALED.getInfo());
                signPatientManageRouteNode.setTaskNodeType(TaskNodeTypeEnum.PHONE_OUTBOUND.getInfo());
                signPatientManageRouteNode.setPhonePushSign(1);
                signPatientManageRouteNode.setScriptInfoId(Objects.isNull(batchSendTaskRecordDto.getScriptInfoId()) ? null : batchSendTaskRecordDto.getScriptInfoId());
                signPatientManageRouteNode.setRobotPublishId(batchSendTaskRecordDto.getRobotPublishId());
                signPatientManageRouteNode.setPhoneTemplateId(Objects.isNull(batchSendTaskRecordDto.getPhoneTemplateId()) ? null : batchSendTaskRecordDto.getPhoneTemplateId());
                signPatientManageRouteNode.setPhoneTemplateName(StringUtils.isBlank(batchSendTaskRecordDto.getPhoneTemplateName()) ? null : batchSendTaskRecordDto.getPhoneTemplateName());
                signPatientManageRouteNode.setPhoneNodeContent(StringUtils.isBlank(batchSendTaskRecordDto.getPhoneNodeContent()) ? null : batchSendTaskRecordDto.getPhoneNodeContent());
                signPatientManageRouteNode.setPhoneRedialTimes(StringUtils.isBlank(batchSendTaskRecordDto.getPhoneRedialTimes()) ? null : batchSendTaskRecordDto.getPhoneRedialTimes());
                signPatientManageRouteNode.setPhoneTimeInterval(Objects.isNull(batchSendTaskRecordDto.getPhoneTimeInterval()) ? null : batchSendTaskRecordDto.getPhoneTimeInterval());
                signPatientManageRouteNode.setPhoneMessageRemind(StringUtils.isBlank(batchSendTaskRecordDto.getPhoneMessageRemind()) ? null : batchSendTaskRecordDto.getPhoneMessageRemind());
                signPatientManageRouteNode.setPhoneMessageTemplateId(Objects.isNull(batchSendTaskRecordDto.getPhoneMessageTemplateId()) ? null : batchSendTaskRecordDto.getPhoneMessageTemplateId());
                signPatientManageRouteNode.setPhoneMessageTemplateName(StringUtils.isBlank(batchSendTaskRecordDto.getPhoneMessageTemplateName()) ? null : batchSendTaskRecordDto.getPhoneMessageTemplateName());
                signPatientManageRouteNode.setPhoneDialMethod(PhoneDialMethodEnum.AI.getInfo());
            }
            if (batchSendTaskRecordDto.getBatchTaskSource().equals(BillSourceEnum.MESSAGE.getInfo())) {
                signPatientManageRouteNode.setTaskNodeType(TaskNodeTypeEnum.TEXT_REMIND.getInfo());
                signPatientManageRouteNode.setMessagePushSign(1);
                signPatientManageRouteNode.setMessageTemplateId(Objects.isNull(batchSendTaskRecordDto.getMessageTemplateId()) ? null : batchSendTaskRecordDto.getMessageTemplateId());
                signPatientManageRouteNode.setMessageTemplateCode(Objects.isNull(batchSendTaskRecordDto.getMessageTemplateCode()) ? null : batchSendTaskRecordDto.getMessageTemplateCode());
                signPatientManageRouteNode.setMessageTemplateName(StringUtils.isBlank(batchSendTaskRecordDto.getMessageTemplateName()) ? null : batchSendTaskRecordDto.getMessageTemplateName());
                signPatientManageRouteNode.setMessageNodeContent(batchSendTaskRecordDto.getMessageNodeContent());

            }
            signPatientManageRouteNode.setRouteCheckStatus(RouteCheckStatusEnum.AGREE.getInfo());
            signPatientManageRouteNode.setNodeExecuteStatus(NodeExecuteStatusEnum.EXECUTING.getInfo());
            signPatientManageRouteNode.setDelFlag(0);
            signPatientManageRouteNode.setCreateBy(SecurityUtils.getUsername());
            signPatientManageRouteNode.setCreateTime(LocalDateTime.now());
            signPatientManageRouteNodes.add(signPatientManageRouteNode);
            //电话变量
            if (batchSendTaskRecordDto.getBatchTaskSource().equals(BillSourceEnum.TELEPHONE.getInfo())) {
                for (String key : keys) {
                    // 获取对象的Class对象
                    Class<?> objClass = batchSendTaskInfo.getClass();
                    // 获取所有属性
                    Field[] fields = objClass.getDeclaredFields();
                    //匹配属性名
                    Field field = Arrays.stream(fields).filter(Objects::nonNull).filter(s -> Objects.equals(s.getName().toUpperCase(), key.replaceAll("_", "").toUpperCase())).findFirst().orElse(null);
                    if (Objects.isNull(field)) {
                        return AjaxResult.error("该模板变量" + key + "不存在!");
                    }
                    BatchSendTaskVariableInfo batchSendTaskVariableInfo = new BatchSendTaskVariableInfo();
                    batchSendTaskVariableInfo.setBatchSendTaskRecordId(batchSendTaskRecordInfo.getId());
                    batchSendTaskVariableInfo.setBatchSendTaskId(batchSendTaskInfo.getId());
                    batchSendTaskVariableInfo.setVariable(key);
                    // 设置可以访问私有变量
                    field.setAccessible(true);
                    batchSendTaskVariableInfo.setVariableAttribute(field.get(batchSendTaskInfo).toString());
                    batchSendTaskVariableInfo.setCreateBy(SecurityUtils.getUsername());
                    batchSendTaskRecordInfo.setCreateTime(LocalDateTime.now());
                    batchSendTaskVariableInfos.add(batchSendTaskVariableInfo);
                }
            }
        }
        //新增节点表主表
        signPatientManageRouteMapper.insertBatch(signPatientManageRoutes);
        //筛如节点表主表id
        for (int i = 0; i < signPatientManageRouteNodes.size(); i++) {
            signPatientManageRouteNodes.get(i).setManageRouteId(signPatientManageRoutes.get(i).getId());
        }
        //新增节点明细表
        signPatientManageRouteNodeMapper.insertBatch(signPatientManageRouteNodes);
        //新增变量表
        if (CollectionUtils.isNotEmpty(batchSendTaskVariableInfos)) {
            batchSendTaskVariableInfoMapper.insertBatchSendTaskVariableInfos(batchSendTaskVariableInfos);
        }
        //电话推送
        if (batchSendTaskRecordDto.getBatchTaskSource().equals(BillSourceEnum.TELEPHONE.getInfo())) {
            //获取医院拨打时间限制
            SysUser sysUser = sysUserMapper.selectUserById(SecurityUtils.getUserId());
            Agency agency = agencyMapper.selectAgencyById(sysUser.getHospitalAgencyId());
            DialTime dialTime = patientInfoImportMainMapper.selectDialTimeById(agency.getId());
            LocalTime localStartTime;
            LocalTime localEndTime;
            LocalTime dateStartTime;
            LocalTime dateEndTime;
            if (Objects.nonNull(dialTime)) {
                localStartTime = LocalTime.parse(dialTime.getDialStartTime());
                localEndTime = LocalTime.parse(dialTime.getDialEndTime());
            } else {
                localStartTime = LocalTime.parse("08:00");
                localEndTime = LocalTime.parse("19:00");
            }
            List<SysDictData> sysDictDataList = iSysDictTypeService.selectDictDataByType(Constants.DIAL_TIME);
            if (CollectionUtils.isEmpty(sysDictDataList) || sysDictDataList.size() != 2) {
                dateStartTime = LocalTime.parse("08:00");
                dateEndTime = LocalTime.parse("19:00");
            } else {
                dateStartTime = LocalTime.parse(sysDictDataList.get(0).getDictValue());
                dateEndTime = LocalTime.parse(sysDictDataList.get(1).getDictValue());
            }
            if (dateStartTime.isAfter(localStartTime)) {
                localStartTime = dateStartTime;
            }
            if (dateEndTime.isBefore(localEndTime)) {
                localEndTime = dateEndTime;
            }
            log.info("创建批量电话推送任务---------------");
            CreateTaskDto createTaskDto = new CreateTaskDto();
            //临时重复测试用，
            String taskName = batchTaskNumber + "-" + batchSendTaskRecordDto.getPhoneTemplateName();
            log.info("任务名称：" + taskName);
            createTaskDto.setTaskName(taskName);
            createTaskDto.setRobotId(batchSendTaskRecordDto.getRobotPublishId());
            createTaskDto.setDialStartDate(batchSendTaskRecordDto.getNodePlanTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            //默认为空，表示不限制终止时间
            createTaskDto.setDialEndDate(batchSendTaskRecordDto.getNodePlanTime().plusDays(2).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            createTaskDto.setForbidDialDate(Arrays.asList(99));
            List<RetryRuleList> retryRuleLists = new ArrayList<>();
            RetryRuleList retryRuleList = new RetryRuleList();
            retryRuleList.setForbidDialStartTime("11:50");
            retryRuleList.setForbidDialEndTime("13:30");
            createTaskDto.setForbidDialTime(retryRuleLists);
            createTaskDto.setRetryTimes(StringUtils.isBlank(batchSendTaskRecordDto.getPhoneRedialTimes()) ? 0 : PhoneRedialTimesEnum.getValueByInfo(batchSendTaskRecordDto.getPhoneRedialTimes()).getValue());
            createTaskDto.setRetryInterval(batchSendTaskRecordDto.getPhoneTimeInterval());
            createTaskDto.setNumTypeFilterList(Arrays.asList(1, 2));
            createTaskDto.setTaskDataCallback(true);
            createTaskDto.setCallBackUrl(callBackUrl + "/taskCallBack");
            createTaskDto.setDialStartTime(localStartTime.format(DateTimeFormatter.ofPattern("HH:mm")));
            createTaskDto.setDialEndTime(localEndTime.format(DateTimeFormatter.ofPattern("HH:mm")));
            //1.创建任务
            String taskId = aiobService.createTask(createTaskDto);
            //2.任务状态变更
            aiobService.updateTaskStatus(taskId, 2);
            //3.导入名单
            List<CustomerInfoDto> customerInfoList = new ArrayList<>();
            signPatientManageRouteNodes.forEach(node -> {
                CustomerInfoDto customerInfoDto = new CustomerInfoDto();
                customerInfoDto.setExtJson(node.getId().toString());
                SignPatientManageRoute signPatientManageRoute = signPatientManageRoutes.stream().filter(Objects::nonNull).filter(item -> item.getId().equals(node.getManageRouteId())).findFirst().orElse(new SignPatientManageRoute());
                BatchSendTaskInfo batchSendTaskInfo = batchSendTaskRecordDto.getList().stream().filter(Objects::nonNull).filter(item -> item.getId().equals(signPatientManageRoute.getBatchSendTaskId())).findFirst().orElse(new BatchSendTaskInfo());
                List<BatchSendTaskVariableInfo> batchSendTaskVariableList = batchSendTaskVariableInfos.stream().filter(Objects::nonNull).filter(item -> item.getBatchSendTaskId().equals(batchSendTaskInfo.getId())).collect(Collectors.toList());
                //校验手机号
                if (StringUtils.isNotBlank(batchSendTaskInfo.getPatientPhone())) {
                    if (regexUtil.regexPhone(batchSendTaskInfo.getPatientPhone())) {
                        customerInfoDto.setMobile(batchSendTaskInfo.getPatientPhone());
                        // 处理变量
                        JSONObject jsonObject = new JSONObject();
                        if (CollectionUtils.isNotEmpty(batchSendTaskVariableList)) {
                            batchSendTaskVariableList.forEach(variable -> {
                                jsonObject.fluentPut(variable.getVariable(), ObjectUtils.isEmpty(variable.getVariableAttribute()) ? "" : variable.getVariableAttribute());
                            });
                        }
                        customerInfoDto.setVar(jsonObject);
                        customerInfoList.add(customerInfoDto);
                    }
                }
            });
            //3.1上传名单
            log.info("任务导入客户名单......");
            ImportTaskDto importTaskDto = new ImportTaskDto();
            importTaskDto.setTaskId(taskId);
            importTaskDto.setSecretType(2);
            importTaskDto.setCustomerInfoList(customerInfoList);
            aiobService.importTask(importTaskDto);
            //根据机器人id查询智能外呼系统的任务id
            int filteredCount = start - end;
            String message = "创建批量电话推送任务执行完成，共计" + start + "条任务";
            if (filteredCount > 0) {
                message += "，过滤重复手机号" + filteredCount + "条";
            }
            log.info(message);
            return AjaxResult.success(message);
        }
        if (batchSendTaskRecordDto.getBatchTaskSource().equals(BillSourceEnum.MESSAGE.getInfo())) {
            log.info("创建批量短信推送任务---------------");
            SmsInfoDTO smsInfoDTO = new SmsInfoDTO();
            List<String> phones = batchSendTaskRecordDto.getList().stream().filter(Objects::nonNull).map(BatchSendTaskInfo::getPatientPhone).distinct().collect(Collectors.toList());
            String phoneString = String.join(",", phones);
            smsInfoDTO.setPhoneNumbers(phoneString);
            smsInfoDTO.setSignName(aliYunSmsTwoConfig.getSignName());
            // 处理变量
            JSONObject jsonObject = new JSONObject();
            if (Objects.nonNull(batchSendTaskRecordDto.getVars())) {
                Set<String> keySet = batchSendTaskRecordDto.getVars().keySet();
                keySet.forEach(variable -> {
                    jsonObject.fluentPut(variable, ObjectUtils.isEmpty(batchSendTaskRecordDto.getVars().get(variable)) ? "" : batchSendTaskRecordDto.getVars().get(variable));
                });
            }
            smsInfoDTO.setTemplateParam(jsonObject);
            // 根据模版id发送
            smsInfoDTO.setTemplateCode(batchSendTaskRecordDto.getMessageTemplateCode());
            smsInfoDTO.setOutId(batchSendTaskRecordInfo.getId().toString());
            Boolean aBoolean = sendSms(smsInfoDTO);
            if (!aBoolean) {
                return AjaxResult.error("短信上传失败");
            }
            int filteredCount = start - end;
            String message = "创建批量短信推送任务执行完成，共计" + start + "条任务";
            if (filteredCount > 0) {
                message += "，过滤重复手机号" + filteredCount + "条";
            }
            log.info(message);
            return AjaxResult.success(message);
        }
        return AjaxResult.success();
    }

    /**
     * 搜素框添加 标签信息
     *
     * @return String
     */
    @Override
    public List<String> getPhysicalExaminationLabel() {
        List<BatchSendTaskLabelInfo> batchSendTaskLabelInfos = batchSendTaskLabelInfoMapper.selectBatchSendTaskLabelInfoList(null);
        if (CollectionUtils.isEmpty(batchSendTaskLabelInfos)) {
            return new ArrayList<>();
        }
        return batchSendTaskLabelInfos.stream().filter(Objects::nonNull).map(BatchSendTaskLabelInfo::getPhysicalExaminationLabel).collect(Collectors.toList());
    }

    /**
     * 变量替换值，发送短信
     */
    public Boolean sendSms(SmsInfoDTO smsInfoDTO) throws ClientException, ServiceException {
        try {
            // 短信发送参数非空性判断
            if (ObjectUtils.isEmpty(smsInfoDTO)) {
                throw new ServiceException("短信发送参数不能为空!");
            }
            if (StringUtils.isBlank(smsInfoDTO.getPhoneNumbers())) {
                throw new ServiceException("待发送手机号不能为空!");
            }
            if (StringUtils.isBlank(smsInfoDTO.getSignName())) {
                throw new ServiceException("短信签名不能为空!");
            }
            if (StringUtils.isBlank(smsInfoDTO.getTemplateCode())) {
                throw new ServiceException("短信模板Code不能为空!");
            }

            // 设置系统的默认连接超时时间和读取超时时间
            System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
            System.setProperty("sun.net.client.defaultReadTimeout", "10000");

            // 初始化acsClient，暂不支持region化
            IClientProfile profile = DefaultProfile.getProfile(aliYunSmsTwoConfig.getRegionId(), aliYunSmsTwoConfig.getAccessKeyId(), aliYunSmsTwoConfig.getAccessKeySecret());
            DefaultProfile.addEndpoint(aliYunSmsTwoConfig.getRegionId(), aliYunSmsTwoConfig.getProduct(), aliYunSmsTwoConfig.getDomain());
            IAcsClient acsClient = new DefaultAcsClient(profile);

            // 组装请求对象
            SendSmsRequest request = new SendSmsRequest();
            request.setPhoneNumbers(smsInfoDTO.getPhoneNumbers());
            request.setSignName(smsInfoDTO.getSignName());
            request.setTemplateCode(smsInfoDTO.getTemplateCode());
            request.setTemplateParam(smsInfoDTO.getTemplateParam().toJSONString());
            request.setOutId(smsInfoDTO.getOutId());
            SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
            // 判断响应的结果
            if (!SUCCESS.equals(sendSmsResponse.getCode())) {
                SmsErrorCodeEnum errorCode = SmsErrorCodeEnum.getMsgByCode(sendSmsResponse.getCode());
                log.error("短信发送失败，错误码：{}，错误信息：{}", sendSmsResponse.getCode(), errorCode.getMessage());
                return false;
            }
            log.info("短信发送成功：code：{}", sendSmsResponse.getCode());
            return true;
        } catch (ClientException e) {
            log.error("发送短信出现异常，异常信息：{}", e.getMessage());
            throw e;
        }
    }
}