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

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.xinelu.common.config.SystemBusinessConfig;
import com.xinelu.common.constant.Constants;
import com.xinelu.common.constant.PhoneMessageRemindConstants;
import com.xinelu.common.constant.TaskCreateTypeConstant;
import com.xinelu.common.enums.ContentedAndRemarkableFlagEnum;
import com.xinelu.common.enums.ErrorStatusEnum;
import com.xinelu.common.enums.NodeExecuteResultStatusEnum;
import com.xinelu.common.enums.NodeExecuteStatusEnum;
import com.xinelu.common.enums.PhoneRedialTimesEnum;
import com.xinelu.common.enums.TaskNodeTypeEnum;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.StringUtils;
import com.xinelu.manage.domain.patientinfo.PatientInfo;
import com.xinelu.manage.domain.patientquestionoptionresult.PatientQuestionOptionResult;
import com.xinelu.manage.domain.patientquestionsubjectresult.PatientQuestionSubjectResult;
import com.xinelu.manage.domain.patientquestionsubmitresult.PatientQuestionSubmitResult;
import com.xinelu.manage.domain.patienttaskexecuterecord.PatientTaskExecuteRecord;
import com.xinelu.manage.domain.patientvisitrecord.PatientVisitRecord;
import com.xinelu.manage.domain.phonedialrecord.PhoneDialRecord;
import com.xinelu.manage.domain.questioninfo.QuestionInfo;
import com.xinelu.manage.domain.questionsubjectoption.QuestionSubjectOption;
import com.xinelu.manage.domain.signpatientmanageroute.SignPatientManageRoute;
import com.xinelu.manage.domain.signpatientmanageroutenode.SignPatientManageRouteNode;
import com.xinelu.manage.domain.signpatientrecord.SignPatientRecord;
import com.xinelu.manage.dto.aiob.CreateDutyDto;
import com.xinelu.manage.dto.aiob.DutyCallbackDataDto;
import com.xinelu.manage.dto.aiob.DutyCallbackDto;
import com.xinelu.manage.mapper.labelfieldcontent.LabelFieldContentMapper;
import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper;
import com.xinelu.manage.mapper.patientquestionoptionresult.PatientQuestionOptionResultMapper;
import com.xinelu.manage.mapper.patientquestionsubjectresult.PatientQuestionSubjectResultMapper;
import com.xinelu.manage.mapper.patientquestionsubmitresult.PatientQuestionSubmitResultMapper;
import com.xinelu.manage.mapper.patienttaskexecuterecord.PatientTaskExecuteRecordMapper;
import com.xinelu.manage.mapper.patientvisitrecord.PatientVisitRecordMapper;
import com.xinelu.manage.mapper.phonedialrecord.PhoneDialRecordMapper;
import com.xinelu.manage.mapper.questioninfo.QuestionInfoMapper;
import com.xinelu.manage.mapper.questionsubject.QuestionSubjectMapper;
import com.xinelu.manage.mapper.questionsubjectoption.QuestionSubjectOptionMapper;
import com.xinelu.manage.mapper.scriptinfotaskinfo.ScriptInfoTaskInfoMapper;
import com.xinelu.manage.mapper.signpatientmanageroute.SignPatientManageRouteMapper;
import com.xinelu.manage.mapper.signpatientmanageroutenode.SignPatientManageRouteNodeMapper;
import com.xinelu.manage.mapper.signpatientrecord.SignPatientRecordMapper;
import com.xinelu.manage.service.aiob.IAIOBService;
import com.xinelu.manage.service.patienttaskstatistics.IPatientTaskStatisticsService;
import com.xinelu.manage.service.yzaiobs.IYZAIOBSService;
import com.xinelu.manage.vo.labelfieldcontent.LabelFieldInfoContentVo;
import com.xinelu.manage.vo.questionsubject.QuestionSubjectVO;
import com.xinelu.manage.vo.yzaiobs.CallRecord;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

/**
 * @description:
 * @author: haown
 * @create: 2025-12-17 17:18
 **/
@Service
@Slf4j
public class YZAIOBSServiceImpl implements IYZAIOBSService {
	@Value("${yzaiobs.url}")
	private String url;
	@Value("${yzaiobs.userId}")
	private String userId;
	@Value("${yzaiobs.roleId}")
	private String roleId;
	@Value("${yzaiobs.routeNum}")
	private Integer routeNum;
	@Value("${yzaiobs.callPhone}")
	private String callPhone;
	@Resource
	private SignPatientManageRouteNodeMapper signPatientManageRouteNodeMapper;
	@Resource
	private PhoneDialRecordMapper phoneDialRecordMapper;
	@Resource
	private ScriptInfoTaskInfoMapper scriptInfoTaskInfoMapper;
	@Resource
	private PatientVisitRecordMapper patientVisitRecordMapper;
	@Resource
	private SignPatientRecordMapper signPatientRecordMapper;
	@Resource
	private SignPatientManageRouteMapper signPatientManageRouteMapper;
	@Resource
	private IAIOBService iaiobService;
	@Resource
	private PatientTaskExecuteRecordMapper patientTaskExecuteRecordMapper;
	@Resource
	private IPatientTaskStatisticsService patientTaskStatisticsService;
	@Resource
	private PatientInfoMapper patientInfoMapper;
	@Resource
	private QuestionInfoMapper questionInfoMapper;
	@Resource
	private PatientQuestionSubmitResultMapper questionSubmitResultMapper;
	@Resource
	private QuestionSubjectMapper questionSubjectMapper;
	@Resource
	private PatientQuestionSubjectResultMapper patientQuestionSubjectResultMapper;
	@Resource
	private QuestionSubjectOptionMapper questionSubjectOptionMapper;
	@Resource
	private PatientQuestionOptionResultMapper patientQuestionOptionResultMapper;
	@Resource
	private LabelFieldContentMapper labelFieldContentMapper;
	@Resource
	private SystemBusinessConfig systemBusinessConfig;

	@Override public String createDuty(CreateDutyDto createDutyDto) {
		createDutyDto.setUserId(userId);
		createDutyDto.setRoleId(roleId);
		createDutyDto.setRouteNum(routeNum);
		createDutyDto.setCallPhone(callPhone);
		//
		RestTemplate restTemplate = new RestTemplate();
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_JSON);
		log.info("创建外呼任务-传输对象:{}", com.alibaba.fastjson.JSONObject.toJSONString(createDutyDto, SerializerFeature.WriteMapNullValue));
		String requestBody = JSON.toJSONString(createDutyDto);
		HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, headers);
		ResponseEntity<String> responseEntity = restTemplate.postForEntity(url + "/duty/createDuty", requestEntity, String.class);
		JSONObject object = JSON.parseObject(responseEntity.getBody());
		if (object == null || object.getBoolean("success") == null || !object.getBoolean("success")) {
			log.info("创建外呼任务失败-原因:{}", object.getString("message"));
			return null;
		}
		log.info("创建外呼任务成功-返回值:{}", com.alibaba.fastjson.JSONObject.toJSONString(object, SerializerFeature.WriteMapNullValue));
		JSONObject data = object.getJSONObject("value");
		Set<String> taskIds = data.keySet();
		Iterator<String> iterator = taskIds.iterator();
		String taskId = iterator.next();
		log.info("创建外呼任务成功-任务id:{}", taskId);
		return taskId;
	}

	@Override public JSONObject taskCallBack(DutyCallbackDto callbackDto) throws ClientException {
		// 从data中获取任务id
		log.info("外呼回调接口开始执行-------");
		JSONArray JSONArr = callbackDto.getData();
		if (!CollectionUtils.isEmpty(JSONArr)) {
			for (int i = 0; i < JSONArr.size(); i++) {
				JSONObject jsonObject = JSONArr.getJSONObject(i);
				log.info("数据{}:{}", i, com.alibaba.fastjson.JSONObject.toJSONString(jsonObject, SerializerFeature.WriteMapNullValue));
				DutyCallbackDataDto dutyCallbackDataDto = JSON.parseObject(jsonObject.toJSONString(), DutyCallbackDataDto.class);
				// 是否发送短信标识
				boolean needSendSms = false;
				// 是否重拨
				boolean needRedial = false;
				// 根据id查询任务
				SignPatientManageRouteNode signPatientManageRouteNode = signPatientManageRouteNodeMapper.selectSignPatientManageRouteNodeById(Long.valueOf(dutyCallbackDataDto.getCustId()));
				if (ObjectUtils.isNotEmpty(signPatientManageRouteNode)) {
					// 标记任务执行状态
					signPatientManageRouteNode.setNodeExecuteStatus(NodeExecuteStatusEnum.EXECUTED.getInfo());

					//接通状态，1-已接通 0-未接通
					//如果未接通
					if (dutyCallbackDataDto.getIsAnswer() != null && dutyCallbackDataDto.getIsAnswer() == 0) {
						// 设置电话拨通情况
						signPatientManageRouteNode.setPhoneNodeExecuteResultStatus(NodeExecuteResultStatusEnum.FAILURE.getInfo());
						// 电话短信提醒
						if (StringUtils.equals(PhoneMessageRemindConstants.NOT_CONNECTED_SEND_MESSAGE, signPatientManageRouteNode.getPhoneMessageRemind())) {
							// 发送短信
							needSendSms = true;
						}

						// 实时任务设置电话重拨
						// 查询拨打次数
						PhoneDialRecord phoneDialRecordQuery = new PhoneDialRecord();
						phoneDialRecordQuery.setManageRouteNodeId(signPatientManageRouteNode.getId());
						List<PhoneDialRecord> phoneDialRecordList = phoneDialRecordMapper.selectPhoneDialRecordList(phoneDialRecordQuery);
						String redialTimes = StringUtils.isEmpty(signPatientManageRouteNode.getPhoneRedialTimes())?"NOT_REPLAY":signPatientManageRouteNode.getPhoneRedialTimes();
						if ((org.apache.commons.collections4.CollectionUtils.isEmpty(phoneDialRecordList) && PhoneRedialTimesEnum.getValueByInfo(redialTimes).getValue() > 0)
							|| phoneDialRecordList.size() + 1 < PhoneRedialTimesEnum.getValueByInfo(redialTimes).getValue()) {
							// 重拨
							needRedial = true;
						} else { //如果不需要重拨，则设置完成时间,问卷提交失败
							// 问卷设置任务完成时间
							if (StringUtils.equals(TaskNodeTypeEnum.QUESTIONNAIRE_SCALE.getInfo(), signPatientManageRouteNode.getTaskNodeType())) {
								signPatientManageRouteNode.setNodeFinishDate(LocalDateTime.now());
								signPatientManageRouteNode.setNodeFinishStatus(NodeExecuteResultStatusEnum.FAILURE.getInfo());
							}
						}
					} else {
						signPatientManageRouteNode.setPhoneNodeExecuteResultStatus(NodeExecuteResultStatusEnum.SUCCESS.getInfo());
						// 问卷设置任务完成时间,问卷提交成功
						if (StringUtils.equals(TaskNodeTypeEnum.QUESTIONNAIRE_SCALE.getInfo(), signPatientManageRouteNode.getTaskNodeType())) {
							signPatientManageRouteNode.setNodeFinishDate(LocalDateTime.now());
							signPatientManageRouteNode.setNodeFinishStatus(NodeExecuteResultStatusEnum.SUCCESS.getInfo());
						}
						if (StringUtils.equals(PhoneMessageRemindConstants.CONNECTED_SEND_MESSAGE, signPatientManageRouteNode.getPhoneMessageRemind())) {
							// 发送短信
							needSendSms = true;
						}
						// 记录通话详情 放到外面执行
						// signPatientManageRouteNode.setPhoneResultJson(com.alibaba.fastjson.JSON.toJSONString(data, SerializerFeature.WriteMapNullValue));
					}

					signPatientManageRouteNode.setPhoneResultJson(com.alibaba.fastjson.JSON.toJSONString(dutyCallbackDataDto, SerializerFeature.WriteMapNullValue));

					signPatientManageRouteNodeMapper.updateSignPatientManageRouteNode(signPatientManageRouteNode);

					// 重拨表任务执行状态修改
					scriptInfoTaskInfoMapper.updateExecuteStatusByNodeId(signPatientManageRouteNode.getId());

					// 任务执行记录
					PatientTaskExecuteRecord patientTaskExecuteRecord = new PatientTaskExecuteRecord();
					BeanUtils.copyProperties(signPatientManageRouteNode, patientTaskExecuteRecord);
					SignPatientManageRoute signPatientManageRoute = signPatientManageRouteMapper.selectSignPatientManageRouteById(signPatientManageRouteNode.getManageRouteId());
					if (ObjectUtils.isNotEmpty(signPatientManageRoute)) {
						patientTaskExecuteRecord.setPatientId(signPatientManageRoute.getPatientId());
						patientTaskExecuteRecord.setPatientName(signPatientManageRoute.getPatientName());
						// 签约记录
						SignPatientRecord signPatientRecord = signPatientRecordMapper.selectByPrimaryKey(signPatientManageRoute.getSignPatientRecordId());
						if (ObjectUtils.isNotEmpty(signPatientRecord)) {
							patientTaskExecuteRecord.setVisitRecordId(signPatientRecord.getPatientVisitRecordId());
						}

						// 发送短信
						if (needSendSms) {
							log.info("发送短信......................");
							iaiobService.sendSms(signPatientManageRoute.getPatientId(), signPatientManageRouteNode);
						}
						// 重拨
						if (needRedial) {
							if (ObjectUtils.isNotEmpty(signPatientRecord)) {
								PatientVisitRecord patientVisitRecord = patientVisitRecordMapper.selectPatientVisitRecordById(signPatientRecord.getPatientVisitRecordId());
								iaiobService.redialInfoSave(signPatientManageRouteNode, patientVisitRecord);
							} else {
								iaiobService.redialInfoSave(signPatientManageRouteNode, null);
							}
						}
					}
					// 增加任务执行记录
					patientTaskExecuteRecord.setManageRouteNodeId(signPatientManageRouteNode.getId());
					patientTaskExecuteRecord.setManageRouteNodeName(signPatientManageRouteNode.getRouteNodeName());
					patientTaskExecuteRecord.setExecuteResult(dutyCallbackDataDto.getNoAnswerReason());
					patientTaskExecuteRecord.setExecuteType(TaskCreateTypeConstant.MANUAL_MATCHE);
					patientTaskExecuteRecord.setExecuteTime(LocalDateTime.now());
					patientTaskExecuteRecord.setCreateTime(LocalDateTime.now());

					// 增加电话拨打记录
					PhoneDialRecord phoneDialRecord = new PhoneDialRecord();
					phoneDialRecord.setPatientId(signPatientManageRoute.getPatientId());
					phoneDialRecord.setManageRouteNodeId(signPatientManageRouteNode.getId());
					phoneDialRecord.setPatientPhone(dutyCallbackDataDto.getPhoneNumber());
					phoneDialRecord.setDialTime(LocalDateTime.now());
					phoneDialRecord.setPhoneTemplateId(signPatientManageRouteNode.getScriptInfoId() + "");
					phoneDialRecord.setPhoneDialMethod(signPatientManageRouteNode.getPhoneDialMethod());
					phoneDialRecord.setErrorCode(dutyCallbackDataDto.getIsAnswer() == 0 ? 1L : 0);
					phoneDialRecord.setErrorStatus(dutyCallbackDataDto.getIsAnswer() == 0 ? ErrorStatusEnum.fail.getValue() : ErrorStatusEnum.success.getValue());
					phoneDialRecord.setCreateTime(LocalDateTime.now());

					phoneDialRecord.setCtUuid(dutyCallbackDataDto.getCallid());
					// 通话录音地址
					phoneDialRecord.setPhoneDialRecordVideo(saveVideo(dutyCallbackDataDto.getMediaPath(), dutyCallbackDataDto.getCustId()));

					phoneDialRecordMapper.insertPhoneDialRecord(phoneDialRecord);

					// 修改任务统计表数据
					//if (patientTaskExecuteRecordMapper.insertPatientTaskExecuteRecord(patientTaskExecuteRecord) > 0) {
					//	// 任务统计表修改
					//	patientTaskStatisticsService.updateNum(signPatientManageRoute.getPatientId(), TaskStatisticsTypeConstants.TASK_EXECUTE_NUM, 1);
					//}

					//接通状态，1-已接通
					if (dutyCallbackDataDto.getIsAnswer() != null && dutyCallbackDataDto.getIsAnswer() == 1) {
						// 问卷记录保存
						if (StringUtils.equals(signPatientManageRouteNode.getTaskNodeType(), TaskNodeTypeEnum.QUESTIONNAIRE_SCALE.getInfo())) {
							parseQuestionInfo(dutyCallbackDataDto.getCallResultType(), dutyCallbackDataDto.getInteractions(),signPatientManageRouteNode, signPatientManageRoute.getPatientId(), patientTaskExecuteRecord.getId());
						}
					}

				}

			}
		}
		JSONObject retObj = new JSONObject();
		retObj.fluentPut("code", 200);
		return retObj;
	}

	@Override
	public String saveVideo(String downloadPath, String nodeId) {
		if (StringUtils.isBlank(downloadPath)) {
			throw new ServiceException("暂未获取到录音，请稍后再试!");
		}
		String url = systemBusinessConfig.getProfile() + systemBusinessConfig.getPhoneDialRecordVideo() + "/" + nodeId + ".wav";
		File outputPath = new File(url);
		File dir = outputPath.getParentFile();
		if (!dir.exists()){
			dir.mkdirs();
		}
		try {
			outputPath.createNewFile(); // 创建文件
			URL fileUrl = new URL(downloadPath);
			HttpURLConnection connection = (HttpURLConnection)fileUrl.openConnection();
			connection.setRequestMethod("GET");
			connection.connect();
			if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
				InputStream inputStream = new BufferedInputStream(connection.getInputStream());
				FileOutputStream outputStream = new FileOutputStream(outputPath);
				byte[] buffer = new byte[1024];
				int bytesRead;
				while ((bytesRead = inputStream.read(buffer)) != -1) {
					outputStream.write(buffer, 0, bytesRead);
				}
				outputStream.close();
				inputStream.close();
				log.info("保存到本地的录音地址：{}", Constants.RESOURCE_PREFIX + systemBusinessConfig.getPhoneDialRecordVideo() + "/" + nodeId + ".wav");
				return Constants.RESOURCE_PREFIX + systemBusinessConfig.getPhoneDialRecordVideo() + "/" + nodeId + ".wav";
			} else {
				throw new ServiceException("下载录音失败，请稍后再试");
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * @description
	 * @Param  callResultType: 命中的意向用,隔开
	 * @Param interactions: 通话内容文本
	 * @return null
	 * @Author haown
	 * @Date 2025-12-25 15:45
	*/
	private void parseQuestionInfo(String callResultTypes, String interactions, SignPatientManageRouteNode node, Long patientInfoId, Long taskExecuteRecordId) {
		PatientInfo patientInfo = patientInfoMapper.selectPatientInfoById(patientInfoId);

		if(StringUtils.isBlank(interactions) || StringUtils.isBlank(callResultTypes)) {
			// 返回一个空的问卷
			genenrateQuestion(node, patientInfo, taskExecuteRecordId);
			return;
		}
		List<String> callResultIntents = Arrays.asList(callResultTypes.split(","));
		// 通话记录解析，先用|分隔完整的问题与答案，再用:分隔角色
		List<CallRecord> recordList = parseRecord(interactions);
		if (CollectionUtils.isEmpty(recordList)) {
			return;
		}

		// 查询患者画像信息
		List<LabelFieldInfoContentVo> labelFieldContentList = labelFieldContentMapper.selectByPatientId(patientInfoId);

		QuestionInfo questionInfo = questionInfoMapper.selectQuestionInfoById(node.getQuestionInfoId());
		// 1、保存patient_question_submit_result
		PatientQuestionSubmitResult patientQuestionSubmitResult = new PatientQuestionSubmitResult();
		patientQuestionSubmitResult.setTaskExecuteRecordId(taskExecuteRecordId);
		patientQuestionSubmitResult.setPatientName(patientInfo.getPatientName());
		patientQuestionSubmitResult.setPatientId(patientInfoId);
		patientQuestionSubmitResult.setManageRouteId(node.getManageRouteId());
		patientQuestionSubmitResult.setManageRouteName(node.getManageRouteName());
		patientQuestionSubmitResult.setManageRouteNodeId(node.getId());
		patientQuestionSubmitResult.setManageRouteNodeName(node.getRouteNodeName());
		patientQuestionSubmitResult.setQuestionInfoId(questionInfo.getId());
		patientQuestionSubmitResult.setDepartmentId(questionInfo.getDepartmentId());
		patientQuestionSubmitResult.setDepartmentName(questionInfo.getDepartmentName());
		patientQuestionSubmitResult.setDiseaseTypeId(questionInfo.getDiseaseTypeId());
		patientQuestionSubmitResult.setDiseaseTypeName(questionInfo.getDiseaseTypeName());
		patientQuestionSubmitResult.setQuestionnaireName(questionInfo.getQuestionnaireName());
		patientQuestionSubmitResult.setQuestionnaireDescription(questionInfo.getQuestionnaireDescription());
		patientQuestionSubmitResult.setAnsweringMethod(questionInfo.getAnsweringMethod());
		patientQuestionSubmitResult.setQuestionnaireId(questionInfo.getQuestionnaireId());
		patientQuestionSubmitResult.setQuestionCount(questionInfo.getQuestionCount());
		patientQuestionSubmitResult.setQuestionnaireTotalScore(questionInfo.getQuestionnaireTotalScore());
		patientQuestionSubmitResult.setResidentId(patientInfo.getResidentId());
		patientQuestionSubmitResult.setCreateTime(LocalDateTime.now());
		questionSubmitResultMapper.insertPatientQuestionSubmitResult(patientQuestionSubmitResult);
		// 2、保存patient_question_subject_result
		final BigDecimal[] totalScore = { BigDecimal.ZERO };
		List<QuestionSubjectVO> questionSubjectList = questionSubjectMapper.selectQuestionSubjectBy(node.getQuestionInfoId());
		questionSubjectList.forEach(questionSubjectVO -> {
			// 判断问题中有无变量，有变量替换变量
			String questionNameAlias = iaiobService.replaceQuestionName(questionSubjectVO.getQuestionNameAlias(), labelFieldContentList);
			// 根据通话记录筛查是否询问该问题
			boolean hasQuestion = false;
			String aiobQuestionName = "";
			for (int i = 0; i < recordList.size(); i++) {
				if (StringUtils.equals(recordList.get(i).getRole(), "speech") && StringUtils.isNotBlank(recordList.get(i).getContextText())
				&& recordList.get(i).getContextText().contains(questionNameAlias.replaceAll("\\p{P}", ""))
				) {
					hasQuestion = true;
					aiobQuestionName = recordList.get(i).getContextText();
					break;
				}
			}

			if (hasQuestion) {

				String finalAiobQuestionName = aiobQuestionName;

				PatientQuestionSubjectResult patientQuestionSubjectResult = new PatientQuestionSubjectResult();
				BeanUtils.copyProperties(questionSubjectVO, patientQuestionSubjectResult);
				patientQuestionSubjectResult.setId(null);
				patientQuestionSubjectResult.setQuestionSubmitResultId(patientQuestionSubmitResult.getId());
				patientQuestionSubjectResult.setCreateTime(LocalDateTime.now());
				//不管是否是 填空题，都 写入回答 文本
				patientQuestionSubjectResult.setFillBlanksAnswer(getReply(recordList, finalAiobQuestionName));

				patientQuestionSubjectResult.setQuestionSubjectId(questionSubjectVO.getId());
				patientQuestionSubjectResultMapper.insertPatientQuestionSubjectResult(patientQuestionSubjectResult);

				// 3、保存patient_question_option_result
				QuestionSubjectOption questionSubjectOptionQuery = new QuestionSubjectOption();
				questionSubjectOptionQuery.setQuestionnaireSubjectId(questionSubjectVO.getId());
				List<QuestionSubjectOption> questionSubjectOptions = questionSubjectOptionMapper.selectQuestionSubjectOptionList(questionSubjectOptionQuery);
				List<PatientQuestionOptionResult> patientQuestionOptionResults = new ArrayList<>();

				questionSubjectOptions.forEach(questionSubjectOption -> {
					PatientQuestionOptionResult patientQuestionOptionResult = new PatientQuestionOptionResult();
					BeanUtils.copyProperties(questionSubjectOption, patientQuestionOptionResult);
					patientQuestionOptionResult.setOptionChooseSign(1);
					// 设置是否选中, 根据回调数据中命中的意向查询
					if (callResultIntents.contains(questionSubjectOption.getIntent())) {
						patientQuestionOptionResult.setOptionChooseSign(0);
					}

					patientQuestionOptionResult.setId(null);
					patientQuestionOptionResult.setCreateTime(LocalDateTime.now());
					patientQuestionOptionResult.setQuestionSubjectResultId(patientQuestionSubjectResult.getId());

					patientQuestionOptionResult.setQuestionSubjectOptionId(questionSubjectOption.getId());

					// 判断是否有附加问题
					if (callResultIntents.contains(questionSubjectOption.getAdditionalQuestionIntent())) {
						//recordList.get(i).getContextText().contains(questionNameAlias.replaceAll("\\p{P}", "")
						patientQuestionOptionResult.setOptionSubmitAnswer(getReply(recordList, questionSubjectOption.getAdditionalQuestion()));
					}
					patientQuestionOptionResults.add(patientQuestionOptionResult);
				});

				if (!CollectionUtils.isEmpty(patientQuestionOptionResults)) {
					List<PatientQuestionOptionResult> remarkableFlag = patientQuestionOptionResults.stream().filter(Objects::nonNull)
						.filter(item -> StringUtils.isNotBlank(item.getRemarkableFlag())
							&& Objects.nonNull(item.getOptionChooseSign()) && item.getOptionChooseSign().equals(0)
							&& ContentedAndRemarkableFlagEnum.REMARKABLE.getInfo().equals(item.getRemarkableFlag()))
						.collect(Collectors.toList());
					if (!CollectionUtils.isEmpty(remarkableFlag)) {
						patientQuestionSubmitResult.setRemarkableFlag(ContentedAndRemarkableFlagEnum.REMARKABLE.getInfo());
					}
					List<PatientQuestionOptionResult> contentedFlag = patientQuestionOptionResults.stream()
						.filter(Objects::nonNull)
						.filter(item -> org.apache.commons.lang3.StringUtils.isNotBlank(item.getContentedFlag())
							&& Objects.nonNull(item.getOptionChooseSign())
							&& item.getOptionChooseSign().equals(0)
							&& ContentedAndRemarkableFlagEnum.DISCONTENTED.getInfo().equals(item.getRemarkableFlag()))
						.collect(Collectors.toList());
					if (!CollectionUtils.isEmpty(contentedFlag)) {
						patientQuestionSubmitResult.setContentedFlag(ContentedAndRemarkableFlagEnum.DISCONTENTED.getInfo());
					}
					patientQuestionOptionResultMapper.saveQuestionOptionList(patientQuestionOptionResults);
				}
				questionSubmitResultMapper.updatePatientQuestionSubmitResult(patientQuestionSubmitResult);


				totalScore[0] = totalScore[0].add(questionSubjectVO.getQuestionScore() == null ? BigDecimal.ZERO : questionSubjectVO.getQuestionScore());
			} else {
				// 没问到问卷中的问题，则保存空问题+空选项
				PatientQuestionSubjectResult patientQuestionSubjectResult = new PatientQuestionSubjectResult();
				BeanUtils.copyProperties(questionSubjectVO, patientQuestionSubjectResult);
				patientQuestionSubjectResult.setId(null);
				patientQuestionSubjectResult.setQuestionSubmitResultId(patientQuestionSubmitResult.getId());
				patientQuestionSubjectResult.setCreateTime(LocalDateTime.now());
				patientQuestionSubjectResultMapper.insertPatientQuestionSubjectResult(patientQuestionSubjectResult);

				// 3、保存空选项
				QuestionSubjectOption questionSubjectOptionQuery = new QuestionSubjectOption();
				questionSubjectOptionQuery.setQuestionnaireSubjectId(questionSubjectVO.getId());
				List<QuestionSubjectOption> questionSubjectOptions = questionSubjectOptionMapper.selectQuestionSubjectOptionList(questionSubjectOptionQuery);
				List<PatientQuestionOptionResult> patientQuestionOptionResults = new ArrayList<>();

				questionSubjectOptions.forEach(questionSubjectOption -> {
					PatientQuestionOptionResult patientQuestionOptionResult = new PatientQuestionOptionResult();
					BeanUtils.copyProperties(questionSubjectOption, patientQuestionOptionResult);
					patientQuestionOptionResult.setOptionChooseSign(1);
					patientQuestionOptionResult.setId(null);
					patientQuestionOptionResult.setCreateTime(LocalDateTime.now());
					patientQuestionOptionResult.setQuestionSubjectResultId(patientQuestionSubjectResult.getId());
					patientQuestionOptionResults.add(patientQuestionOptionResult);
				});
				if(!CollectionUtils.isEmpty(patientQuestionOptionResults)) {
					log.info("问卷选项结果:{}", patientQuestionOptionResults);
					patientQuestionOptionResultMapper.saveQuestionOptionList(patientQuestionOptionResults);
				}
				totalScore[0] = totalScore[0].add(BigDecimal.ZERO);
			}
		});

		// 4、更新总得分
		//patientQuestionSubmitResult.setTotalScore(totalScore[0]);
		//questionSubmitResultMapper.updatePatientQuestionSubmitResult(patientQuestionSubmitResult);
	}

	@Override
	public List<CallRecord> parseRecord(String interactions) {
		if (StringUtils.isBlank(interactions)) {
			return null;
		}
		// 先用|分隔完整的问题与答案，再用:分隔角色
		List<CallRecord> retList = new ArrayList<>();
		List<String> records = Arrays.asList(interactions.split("\\|"));
		if (CollectionUtils.isEmpty(records)) {
			return null;
		}
		for (String record : records) {
			CallRecord callRecord = new CallRecord();
			String[] str1 = record.split(":");
			callRecord.setRole(str1[0]);
			if (StringUtils.equals("机器人", str1[0])) {
				callRecord.setRole("speech");
				if (str1.length > 1 && StringUtils.isNotBlank(str1[1])) {
					// 用^分隔
					String[] content = str1[1].split("\\^");
					for (int i = 0; i < content.length; i++) {
						if (StringUtils.contains(content[i], "txt=")) {
							callRecord.setContextText(content[i].replaceAll("txt=", ""));
						}
					}
				}
			} else if (StringUtils.equals("用户", str1[0])) {
				callRecord.setRole("voice");
				if (str1.length > 1 && StringUtils.isNotBlank(str1[1])) {
					callRecord.setContextText(str1[1]);
				}
			}

			retList.add(callRecord);
		}
		return retList;
	}

	/**
	 * @description 根据通话记录获取回复
	 * @Param  callRecordList： 通话记录列表
	 * @Param question: 问题名称
	 * @return 回复内容
	 * @Author haown
	 * @Date 2025-12-26 9:40
	*/
	private String getReply(List<CallRecord> callRecordList, String question) {
		for (int i = 0; i < callRecordList.size(); i++) {
			if (StringUtils.equals(callRecordList.get(i).getContextText(), question) && i+1 <= callRecordList.size() && StringUtils.equals("voice", callRecordList.get(i+1).getRole())) {
				// 问题可能出现多次补充的情况，用[p2000]标签来标识是补充的问题。
				if (callRecordList.get(i).getContextText().contains("[p2000]")) {
					// 查找通话内容中包含[p2000]的用户回复
					return getReplyByLabel(callRecordList, "[p2000]", i);
				} else {
					return callRecordList.get(i+1).getContextText();
				}

			}
		}
		return null;
	}

	private String getReplyByLabel(List<CallRecord> callRecordList, String label, int i) {
		List<CallRecord> subRecord = callRecordList.subList(i, callRecordList.size());
		StringBuffer reply = new StringBuffer();
		if (!CollectionUtils.isEmpty(subRecord)) {
			for (int j = 0; j < subRecord.size(); j++) {
				if (StringUtils.isNotBlank(subRecord.get(j).getContextText()) && subRecord.get(j).getContextText().contains(label) && j+1 <= subRecord.size() && StringUtils.equals("voice",subRecord.get(j+1).getRole())) {
					reply.append(StringUtils.isBlank(subRecord.get(j+1).getContextText()) ? "" : subRecord.get(j+1).getContextText());
				}
			}
		}
		return reply.toString();
	}

	private void genenrateQuestion(SignPatientManageRouteNode node, PatientInfo patientInfo, Long taskExecuteRecordId) {
		QuestionInfo questionInfo = questionInfoMapper.selectQuestionInfoById(node.getQuestionInfoId());
		// 1、保存patient_question_submit_result
		PatientQuestionSubmitResult patientQuestionSubmitResult = new PatientQuestionSubmitResult();
		patientQuestionSubmitResult.setTaskExecuteRecordId(taskExecuteRecordId);
		patientQuestionSubmitResult.setPatientName(patientInfo.getPatientName());
		patientQuestionSubmitResult.setPatientId(patientInfo.getId());
		patientQuestionSubmitResult.setManageRouteId(node.getManageRouteId());
		patientQuestionSubmitResult.setManageRouteName(node.getManageRouteName());
		patientQuestionSubmitResult.setManageRouteNodeId(node.getId());
		patientQuestionSubmitResult.setManageRouteNodeName(node.getRouteNodeName());
		patientQuestionSubmitResult.setQuestionInfoId(questionInfo.getId());
		patientQuestionSubmitResult.setDepartmentId(questionInfo.getDepartmentId());
		patientQuestionSubmitResult.setDepartmentName(questionInfo.getDepartmentName());
		patientQuestionSubmitResult.setDiseaseTypeId(questionInfo.getDiseaseTypeId());
		patientQuestionSubmitResult.setDiseaseTypeName(questionInfo.getDiseaseTypeName());
		patientQuestionSubmitResult.setQuestionnaireName(questionInfo.getQuestionnaireName());
		patientQuestionSubmitResult.setQuestionnaireDescription(questionInfo.getQuestionnaireDescription());
		patientQuestionSubmitResult.setAnsweringMethod(questionInfo.getAnsweringMethod());
		patientQuestionSubmitResult.setQuestionnaireId(questionInfo.getQuestionnaireId());
		patientQuestionSubmitResult.setQuestionCount(questionInfo.getQuestionCount());
		patientQuestionSubmitResult.setQuestionnaireTotalScore(questionInfo.getQuestionnaireTotalScore());
		patientQuestionSubmitResult.setResidentId(patientInfo.getResidentId());
		patientQuestionSubmitResult.setCreateTime(LocalDateTime.now());
		questionSubmitResultMapper.insertPatientQuestionSubmitResult(patientQuestionSubmitResult);
		// 2、保存patient_question_subject_result
		List<QuestionSubjectVO> questionSubjectList = questionSubjectMapper.selectQuestionSubjectBy(node.getQuestionInfoId());
		questionSubjectList.forEach(questionSubjectVO -> {
			PatientQuestionSubjectResult patientQuestionSubjectResult = new PatientQuestionSubjectResult();
			BeanUtils.copyProperties(questionSubjectVO, patientQuestionSubjectResult);
			patientQuestionSubjectResult.setId(null);
			patientQuestionSubjectResult.setQuestionSubmitResultId(patientQuestionSubmitResult.getId());
			patientQuestionSubjectResult.setCreateTime(LocalDateTime.now());
			//不管是否是 填空题，都 写入回答 文本
			patientQuestionSubjectResult.setFillBlanksAnswer(null);

			patientQuestionSubjectResult.setQuestionSubjectId(questionSubjectVO.getId());
			patientQuestionSubjectResultMapper.insertPatientQuestionSubjectResult(patientQuestionSubjectResult);

			// 3、保存patient_question_option_result
			QuestionSubjectOption questionSubjectOptionQuery = new QuestionSubjectOption();
			questionSubjectOptionQuery.setQuestionnaireSubjectId(questionSubjectVO.getId());
			List<QuestionSubjectOption> questionSubjectOptions = questionSubjectOptionMapper.selectQuestionSubjectOptionList(questionSubjectOptionQuery);
			List<PatientQuestionOptionResult> patientQuestionOptionResults = new ArrayList<>();

			questionSubjectOptions.forEach(questionSubjectOption -> {
				PatientQuestionOptionResult patientQuestionOptionResult = new PatientQuestionOptionResult();
				BeanUtils.copyProperties(questionSubjectOption, patientQuestionOptionResult);
				patientQuestionOptionResult.setOptionChooseSign(1);
				patientQuestionOptionResult.setId(null);
				patientQuestionOptionResult.setCreateTime(LocalDateTime.now());
				patientQuestionOptionResult.setQuestionSubjectResultId(patientQuestionSubjectResult.getId());

				patientQuestionOptionResult.setQuestionSubjectOptionId(questionSubjectOption.getId());

				patientQuestionOptionResults.add(patientQuestionOptionResult);
			});

			if (!CollectionUtils.isEmpty(patientQuestionOptionResults)) {
				List<PatientQuestionOptionResult> remarkableFlag = patientQuestionOptionResults.stream()
					.filter(Objects::nonNull)
					.filter(item -> StringUtils.isNotBlank(item.getRemarkableFlag()) && Objects.nonNull(item.getOptionChooseSign()) && item.getOptionChooseSign().equals(0) && ContentedAndRemarkableFlagEnum.REMARKABLE.getInfo().equals(item.getRemarkableFlag()))
					.collect(Collectors.toList());
				if (!CollectionUtils.isEmpty(remarkableFlag)) {
					patientQuestionSubmitResult.setRemarkableFlag(ContentedAndRemarkableFlagEnum.REMARKABLE.getInfo());
				}
				List<PatientQuestionOptionResult> contentedFlag = patientQuestionOptionResults.stream()
					.filter(Objects::nonNull)
					.filter(item -> org.apache.commons.lang3.StringUtils.isNotBlank(item.getContentedFlag()) && Objects.nonNull(item.getOptionChooseSign()) && item.getOptionChooseSign().equals(0) && ContentedAndRemarkableFlagEnum.DISCONTENTED.getInfo().equals(item.getRemarkableFlag()))
					.collect(Collectors.toList());
				if (!CollectionUtils.isEmpty(contentedFlag)) {
					patientQuestionSubmitResult.setContentedFlag(ContentedAndRemarkableFlagEnum.DISCONTENTED.getInfo());
				}
				log.info("问卷选项结果:{}", patientQuestionOptionResults);
				patientQuestionOptionResultMapper.saveQuestionOptionList(patientQuestionOptionResults);
			}
			questionSubmitResultMapper.updatePatientQuestionSubmitResult(patientQuestionSubmitResult);

		});
	}
}
