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

import com.xinelu.common.constant.SignRecordServiceStatusConstants;
import com.xinelu.common.constant.TaskCreateTypeConstant;
import com.xinelu.common.enums.NodeExecuteStatusEnum;
import com.xinelu.common.enums.RouteCheckStatusEnum;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.common.utils.StringUtils;
import com.xinelu.common.utils.bean.BeanUtils;
import com.xinelu.manage.domain.patientinfo.PatientInfo;
import com.xinelu.manage.domain.signpatientinformed.SignPatientInformed;
import com.xinelu.manage.domain.signpatientmanageroute.SignPatientManageRoute;
import com.xinelu.manage.domain.signpatientmanageroutenode.SignPatientManageRouteNode;
import com.xinelu.manage.domain.signpatientpackage.SignPatientPackage;
import com.xinelu.manage.domain.signpatientpackagehardware.SignPatientPackageHardware;
import com.xinelu.manage.domain.signpatientrecord.SignPatientRecord;
import com.xinelu.manage.domain.signroutetriggercondition.SignRouteTriggerCondition;
import com.xinelu.manage.domain.specialdiseasenode.SpecialDiseaseNode;
import com.xinelu.manage.domain.specialdiseaseroute.SpecialDiseaseRoute;
import com.xinelu.manage.domain.specialdiseasetriggercondition.SpecialDiseaseTriggerCondition;
import com.xinelu.manage.dto.signpatientpackage.SignPatientPackageSaveDto;
import com.xinelu.manage.dto.signpatientrecord.IntentionalSignDto;
import com.xinelu.manage.dto.signpatientrecord.SignPatientAddDto;
import com.xinelu.manage.dto.signpatientrecord.SignPatientListDto;
import com.xinelu.manage.dto.signpatientrecord.SignPatientStatusDto;
import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper;
import com.xinelu.manage.mapper.signpatientinformed.SignPatientInformedMapper;
import com.xinelu.manage.mapper.signpatientmanageroute.SignPatientManageRouteMapper;
import com.xinelu.manage.mapper.signpatientmanageroutenode.SignPatientManageRouteNodeMapper;
import com.xinelu.manage.mapper.signpatientpackage.SignPatientPackageMapper;
import com.xinelu.manage.mapper.signpatientpackagehardware.SignPatientPackageHardwareMapper;
import com.xinelu.manage.mapper.signpatientrecord.SignPatientRecordMapper;
import com.xinelu.manage.mapper.signroutetriggercondition.SignRouteTriggerConditionMapper;
import com.xinelu.manage.mapper.specialdiseasenode.SpecialDiseaseNodeMapper;
import com.xinelu.manage.mapper.specialdiseaseroute.SpecialDiseaseRouteMapper;
import com.xinelu.manage.mapper.specialdiseasetriggercondition.SpecialDiseaseTriggerConditionMapper;
import com.xinelu.manage.service.signpatientrecord.ISignPatientRecordService;
import com.xinelu.manage.vo.signpatientrecord.SignPatientInfoVo;
import com.xinelu.manage.vo.signpatientrecord.SignPatientListVo;
import com.xinelu.manage.vo.signpatientrecord.SignPatientRecordVo;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
* @author haown
* @description 针对表【sign_patient_record(签约记录表)】的数据库操作Service实现
* @createDate 2024-02-28 15:05:02
*/
@Service
public class SignPatientRecordServiceImpl implements ISignPatientRecordService {

	@Resource
	private SignPatientRecordMapper signPatientRecordMapper;

	@Resource
	private SignPatientPackageMapper signPatientPackageMapper;
	@Resource
	private SignPatientPackageHardwareMapper hardwareMapper;
	@Resource
	private SignPatientInformedMapper informedMapper;
	@Resource
	private PatientInfoMapper patientInfoMapper;
	@Resource
	private SignPatientPackageHardwareMapper signPatientPackageHardwareMapper;
	@Resource
	private SignPatientInformedMapper signPatientInformedMapper;
	@Resource
	private SpecialDiseaseRouteMapper specialDiseaseRouteMapper;
	@Resource
	private SignPatientManageRouteMapper signPatientManageRouteMapper;
	@Resource
	private SpecialDiseaseNodeMapper specialDiseaseNodeMapper;
	@Resource
	private SignPatientManageRouteNodeMapper manageRouteNodeMapper;
	@Resource
	private SpecialDiseaseTriggerConditionMapper triggerConditionMapper;
	@Resource
	private SignRouteTriggerConditionMapper signRouteTriggerConditionMapper;

	@Override public List<SignPatientListVo> selectList(SignPatientListDto signPatientRecord) {
		return signPatientRecordMapper.selectList(signPatientRecord);
	}

	@Override public SignPatientInfoVo getByRecordId(Long id) {
		// 查询签约信息、签约服务包、签约路径
		SignPatientInfoVo signPatientInfoVo = signPatientRecordMapper.getByRecordId(id);
		// 根据签约记录主键查询设备列表
		SignPatientPackageHardware queryDevice = new SignPatientPackageHardware();
		queryDevice.setSignPatientRecordId(id);
		List<SignPatientPackageHardware> devices = signPatientPackageHardwareMapper.selectSignPatientPackageHardwareList(queryDevice);
		signPatientInfoVo.setSignDevices(devices);
		// 签约知情同意书
		SignPatientInformed signPatientInformed = new SignPatientInformed();
		signPatientInformed.setSignPatientRecordId(id);
		List<SignPatientInformed> informeds = signPatientInformedMapper.selectSignPatientInformedList(signPatientInformed);
		signPatientInfoVo.setSignPatientInformeds(informeds);
		return signPatientInfoVo;
	}

	@Override public List<SignPatientRecordVo> getByPatient(Long patientId) {
		return signPatientRecordMapper.getByPatient(patientId);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int add(SignPatientAddDto body) {
		SignPatientPackageSaveDto signPatientPackageDto = body.getSignPackage();
		if (ObjectUtils.isEmpty(signPatientPackageDto)) {
			throw new ServiceException("请选择服务包");
		}
		if (signPatientPackageDto.getServicePackageId() == null) {
			throw new ServiceException("请选择服务包");
		}
		if (ObjectUtils.isNotEmpty(body.getRecord())) {
			SignPatientRecord signPatientRecord = body.getRecord();
			if (signPatientRecord.getPatientId() == null) {
				throw new ServiceException("请选择签约居民");
			}
			PatientInfo patient = patientInfoMapper.selectPatientInfoById(signPatientRecord.getPatientId());
			if (ObjectUtils.isEmpty(patient)) {
				throw new ServiceException("请选择签约居民");
			}
			signPatientRecord.setServiceStatus(SignRecordServiceStatusConstants.SERVICE_CENTER);
			signPatientRecord.setDelFlag(0);
			signPatientRecord.setPaymentStatus(signPatientPackageDto.getPackagePaymentStatus());
			signPatientRecord.setSignTime(LocalDateTime.now());
			signPatientRecord.setSignStatus(SignRecordServiceStatusConstants.IN_SIGN);
			signPatientRecord.setPrice(signPatientPackageDto.getPackagePrice());
			signPatientRecord.setCreateTime(LocalDateTime.now());
			signPatientRecord.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
			// 保存签约记录
			int flag;
			if (StringUtils.equals("sign", body.getSignCategory())) { // 签约，修改意向签约记录状态
				signPatientRecord.setId(patient.getSignPatientRecordId());
				flag = signPatientRecordMapper.updateByPrimaryKeySelective(signPatientRecord);
			} else {
				signPatientRecord.setId(null);
				flag = signPatientRecordMapper.insert(signPatientRecord);
			}
			// 签约信息保存到患者表
			patient.setSignPatientRecordId(signPatientRecord.getId());
			patient.setSignStatus(SignRecordServiceStatusConstants.IN_SIGN);
			patient.setServiceStatus(SignRecordServiceStatusConstants.SERVICE_CENTER);
			patient.setSignTime(LocalDateTime.now());
			patientInfoMapper.updatePatientInfo(patient);
			if (flag > 0) {
				// 保存签约服务包信息
				SignPatientPackage signPatientPackage = new SignPatientPackage();

				// 服务开始时间、服务结束时间
				BeanUtils.copyBeanProp(signPatientPackage, signPatientPackageDto);
				signPatientPackage.setSignPatientRecordId(signPatientRecord.getId());
				signPatientPackage.setPatientId(signPatientRecord.getPatientId());
				signPatientPackage.setServiceStartTime(signPatientPackageDto.getServiceStartTime().atStartOfDay());
				signPatientPackage.setServiceEndTime(signPatientPackageDto.getServiceEndTime().atTime(23,59,59));
				signPatientPackage.setCreateTime(LocalDateTime.now());
				signPatientPackage.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
				signPatientPackageMapper.insertSignPatientPackage(signPatientPackage);

				// 保存管理路径
				if (body.getRoute() != null) {
					SignPatientManageRoute signPatientManageRoute = body.getRoute();
					SpecialDiseaseRoute specialDiseaseRoute = specialDiseaseRouteMapper.selectSpecialDiseaseRouteById(signPatientManageRoute.getRouteId());
					BeanUtils.copyBeanProp(signPatientManageRoute, specialDiseaseRoute);
					signPatientManageRoute.setSignPatientRecordId(signPatientRecord.getId());
					signPatientManageRoute.setPatientId(patient.getId());
					signPatientManageRoute.setId(null);
					signPatientManageRoute.setRouteId(specialDiseaseRoute.getId());
					signPatientManageRoute.setTaskCreateType(TaskCreateTypeConstant.MANUAL_MATCHE);
					signPatientManageRoute.setCreateTime(LocalDateTime.now());
					signPatientManageRoute.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
					signPatientManageRouteMapper.insertSignPatientManageRoute(signPatientManageRoute);
					// 保存管理节点
					SpecialDiseaseNode specialDiseaseNode = new SpecialDiseaseNode();
					specialDiseaseNode.setRouteId(signPatientManageRoute.getRouteId());
					List<SpecialDiseaseNode> nodeList = specialDiseaseNodeMapper.selectSpecialDiseaseNodeList(specialDiseaseNode);
					if (CollectionUtils.isEmpty(nodeList)) {
						throw new ServiceException("该管理任务没有任务节点");
					}
					List<SignPatientManageRouteNode> manageNodeList = nodeList.stream().map(node -> {
						SignPatientManageRouteNode manageRouteNode = new SignPatientManageRouteNode();
						BeanUtils.copyBeanProp(manageRouteNode, node);
						manageRouteNode.setManageRouteId(signPatientManageRoute.getId());
						manageRouteNode.setManageRouteName(signPatientManageRoute.getRouteName());
						manageRouteNode.setId(null);
						manageRouteNode.setRouteCheckStatus(RouteCheckStatusEnum.AGREE.name());
						manageRouteNode.setRouteCheckDate(LocalDateTime.now());
						manageRouteNode.setRouteCheckRemark("签约自动审核通过");
						manageRouteNode.setNodeExecuteStatus(NodeExecuteStatusEnum.UNEXECUTED.name());
						manageRouteNode.setCreateTime(LocalDateTime.now());
						manageRouteNode.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
						return manageRouteNode;
					}).collect(Collectors.toList());
					// 批量保存
					manageRouteNodeMapper.insertBatch(manageNodeList);
					// 保存触发条件
					SpecialDiseaseTriggerCondition triggerConditionQuery = new SpecialDiseaseTriggerCondition();
					triggerConditionQuery.setRouteId(signPatientManageRoute.getRouteId());
					List<SpecialDiseaseTriggerCondition> triggerConditions = triggerConditionMapper.selectSpecialDiseaseTriggerConditionList(triggerConditionQuery);
					List<SignRouteTriggerCondition> routeTriggerConditionList =  triggerConditions.stream().map(item->{
						SignRouteTriggerCondition signRouteTriggerCondition = new SignRouteTriggerCondition();
						BeanUtils.copyBeanProp(signRouteTriggerCondition, item);
						signRouteTriggerCondition.setPatientManageRouteId(signPatientManageRoute.getId());
						signRouteTriggerCondition.setRouteName(signPatientManageRoute.getRouteName());
						signRouteTriggerCondition.setId(null);
						return signRouteTriggerCondition;
					}).collect(Collectors.toList());
					signRouteTriggerConditionMapper.insertBatch(routeTriggerConditionList);
				}

				// 保存硬件
				if (!CollectionUtils.isEmpty(body.getDevices())) {
					for(SignPatientPackageHardware hardware : body.getDevices()) {
						hardware.setSignPatientRecordId(signPatientRecord.getId());
						hardwareMapper.insertSignPatientPackageHardware(hardware);
					}
				}

				// 保存告知书
				if (!CollectionUtils.isEmpty(body.getInformeds())) {
					for (SignPatientInformed informed : body.getInformeds()) {
						informed.setSignPatientRecordId(signPatientRecord.getId());
						informed.setPatientId(signPatientRecord.getPatientId());
						informedMapper.insertSignPatientInformed(informed);
					}
				}
			}
			return flag;
		}
		return 0;
	}

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateSignStatus(SignPatientStatusDto patientCancelSignDto) {
        if (patientCancelSignDto.getPatientId() == null) {
            throw new ServiceException("居民主键不能为空");
        }
        // 修改签约记录状态
        SignPatientRecord signRecord = new SignPatientRecord();
        signRecord.setId(patientCancelSignDto.getId());
        signRecord.setSignStatus(patientCancelSignDto.getSignStatus());
        signRecord.setServiceStatus(patientCancelSignDto.getServiceStatus());
        signRecord.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName());
        signRecord.setUpdateTime(LocalDateTime.now());
        signRecord.setSeparateReason(patientCancelSignDto.getSeparateReason());
        if (StringUtils.equals(SignRecordServiceStatusConstants.SEPARATE_SIGN, patientCancelSignDto.getSignStatus())) {

			PatientInfo patient = patientInfoMapper.selectPatientInfoById(patientCancelSignDto.getPatientId());
			// 签约信息保存到患者表
			patient.setSignStatus(patientCancelSignDto.getSignStatus());
			patient.setServiceStatus(patientCancelSignDto.getServiceStatus());
			patientInfoMapper.updatePatientInfo(patient);
		}
		return signPatientRecordMapper.updateByPrimaryKeySelective(signRecord);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int intentionalSign(IntentionalSignDto intentionalSignDto) {
		PatientInfo patientInfo = patientInfoMapper.selectPatientInfoById(intentionalSignDto.getPatientId());
		if (ObjectUtils.isEmpty(patientInfo)) {
			throw new ServiceException("未找到该居民");
		}
		// 查询当前居民签约状态是否已签约
		if (StringUtils.equals(SignRecordServiceStatusConstants.SERVICE_CENTER, patientInfo.getServiceStatus())) {
			throw new ServiceException("该居民已签约!");
		}

		patientInfo.setServiceStatus(SignRecordServiceStatusConstants.INTENTIONAL_SIGNING);
		SignPatientRecord signRecord = new SignPatientRecord();
		// 患者信息保存到签约表
		BeanUtils.copyBeanProp(signRecord, patientInfo);
		signRecord.setSignDiagnosis(patientInfo.getMainDiagnosis());
		signRecord.setBillingDoctorId(intentionalSignDto.getBillingDoctorId());
		signRecord.setBillingDoctorName(intentionalSignDto.getBillingDoctorName());
		signRecord.setIntentionalSource(intentionalSignDto.getIntentionalSource());
		signRecord.setIntentionalTime(LocalDateTime.now());
		signRecord.setPatientId(patientInfo.getId());
		signRecord.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
		signRecord.setCreateTime(LocalDateTime.now());
		signRecord.setId(null);
		int flag = signPatientRecordMapper.insertSelective(signRecord);
		if (flag > 0) {
			patientInfo.setSignPatientRecordId(signRecord.getId());
			patientInfoMapper.updatePatientInfo(patientInfo);
		}
		return flag;
	}
}
