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

import com.xinelu.common.annotation.DataScope;
import com.xinelu.common.constant.NodeTypeConstants;
import com.xinelu.common.constant.PatientTypeConstants;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.BaseUtil;
import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.common.utils.StringUtils;
import com.xinelu.common.utils.bean.BeanUtils;
import com.xinelu.common.utils.regex.RegexUtil;
import com.xinelu.manage.domain.agency.Agency;
import com.xinelu.manage.domain.department.Department;
import com.xinelu.manage.domain.patientinfo.PatientInfo;
import com.xinelu.manage.domain.patientprehospitalization.PatientPreHospitalization;
import com.xinelu.manage.domain.patientvisitrecord.PatientVisitRecord;
import com.xinelu.manage.dto.patientinfo.PatientInfoDto;
import com.xinelu.manage.dto.patientvisitrecord.PatientVisitRecordDto;
import com.xinelu.manage.mapper.agency.AgencyMapper;
import com.xinelu.manage.mapper.department.DepartmentMapper;
import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper;
import com.xinelu.manage.mapper.patientprehospitalization.PatientPreHospitalizationMapper;
import com.xinelu.manage.service.patientinfo.IPatientInfoService;
import com.xinelu.manage.service.patientprehospitalization.IPatientPreHospitalizationService;
import com.xinelu.manage.service.patientvisitrecord.IPatientVisitRecordService;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author haown
 * @description 针对表【patient_pre_hospitalization(预住院患者表)】的数据库操作Service实现
 * @createDate 2024-03-08 10:25:39
 */
@Service
public class PatientPreHospitalizationServiceImpl implements IPatientPreHospitalizationService {

    @Resource
    private PatientPreHospitalizationMapper preHospitalizationMapper;

    @Resource
    private IPatientInfoService patientInfoService;

    @Resource
    private AgencyMapper agencyMapper;

    @Resource
    private DepartmentMapper departmentMapper;

	@Resource
	private IPatientVisitRecordService patientVisitRecordService;

    @Resource
    private RegexUtil regexUtil;

	@Resource
	private PatientInfoMapper patientInfoMapper;

    @Override
    public int insert(PatientPreHospitalization preHospitalization) {
		// 根据身份证号设置出生日期、性别
	    if (StringUtils.isBlank(preHospitalization.getCardNo())) {
			throw new ServiceException("请填写正确的身份证号!");
	    }
		if (preHospitalization.getBirthDate() == null) {
			preHospitalization.setBirthDate(BaseUtil.getBirthday(preHospitalization.getCardNo()));
		}
	    if (StringUtils.isBlank(preHospitalization.getSex())) {
		    preHospitalization.setSex(BaseUtil.getGender(preHospitalization.getCardNo()));
	    }
        // 根据身份证号+医院id查询是否有患者信息
        PatientInfoDto patientInfoDto = new PatientInfoDto();
        patientInfoDto.setCardNo(preHospitalization.getCardNo());
		patientInfoDto.setHospitalAgencyId(preHospitalization.getHospitalAgencyId());
        List<PatientInfo> patientList = patientInfoService.selectAllPatientList(patientInfoDto);
		PatientInfo patientInfo = new PatientInfo();
        if (CollectionUtils.isEmpty(patientList)) {
            // 保存患者信息
            BeanUtils.copyBeanProp(patientInfo, preHospitalization);
            patientInfo.setPatientType(PatientTypeConstants.PRE_HOSPITALIZED_PATIENT);
	        PatientInfo saveObj = patientInfoService.insertPatientInfo(patientInfo);
            preHospitalization.setPatientId(saveObj.getId());
	        preHospitalization.setResidentId(saveObj.getResidentId());
        } else {
            // 修改患者信息
            patientInfo = patientList.get(0);
			Long patientId = patientInfo.getId();
            BeanUtils.copyBeanProp(patientInfo, preHospitalization);
            patientInfo.setPatientType(PatientTypeConstants.PRE_HOSPITALIZED_PATIENT);
			patientInfo.setId(patientId);
	        patientInfoService.updatePatientInfo(patientInfo);
            preHospitalization.setPatientId(patientInfo.getId());
	        preHospitalization.setResidentId(patientInfo.getResidentId());
        }
        // 保存预住院信息
        preHospitalization.setDelFlag(0);
        preHospitalization.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
        preHospitalization.setCreateTime(LocalDateTime.now());
		int flag = preHospitalizationMapper.insertSelective(preHospitalization);
	    patientInfo.setPatientPreHospitalizationId(preHospitalization.getId());
	    patientInfoMapper.updatePatientInfoSelective(patientInfo);
	    return flag;
    }

    @Override
    @DataScope(agencyAlias = "p",userAlias = "p.certificate_issuing_doctor_id")
    public List<PatientPreHospitalization> selectList(PatientInfoDto patientInfo) {
        return preHospitalizationMapper.selectList(patientInfo);
    }

    @Override
    @Transactional
    public int update(PatientPreHospitalization preHospitalization) {
        // 修改患者信息
        PatientInfo patientInfo = patientInfoService.selectPatientInfoById(preHospitalization.getPatientId());
        Long patientId = patientInfo.getId();
        BeanUtils.copyBeanProp(patientInfo, preHospitalization);
        patientInfo.setId(patientId);
        patientInfoService.updatePatientInfo(patientInfo);
        return preHospitalizationMapper.updateByPrimaryKeySelective(preHospitalization);
    }


    @Override
    @Transactional
    public int deleteByIds(Long[] ids) {
		for (Long id : ids) {
			// 将患者状态还原为上一个状态
			PatientPreHospitalization patientPreHospitalization = preHospitalizationMapper.selectByPrimaryKey(id);
			PatientInfo patientInfo = patientInfoService.selectPatientInfoById(patientPreHospitalization.getPatientId());
			PatientVisitRecordDto patientVisitRecordDto = new PatientVisitRecordDto();
			patientVisitRecordDto.setHospitalAgencyId(patientPreHospitalization.getHospitalAgencyId());
			patientVisitRecordDto.setPatientId(patientPreHospitalization.getPatientId());
			PatientVisitRecord patientVisitRecord = patientVisitRecordService.getLastRecord(patientVisitRecordDto);
			if (ObjectUtils.isEmpty(patientVisitRecord)) {
				// 患者的预住院信息置空
				setPreHospitalizationInfoNull(patientInfo);
			} else {
				// 将患者信息更改为就诊信息
				Long patientId = patientInfo.getId();
				BeanUtils.copyBeanProp(patientInfo, patientVisitRecord);
				patientInfo.setPatientVisitRecordId(patientVisitRecord.getId());
				patientVisitRecordService.setPatientType(patientInfo, patientVisitRecord);
				patientInfo.setId(patientId);
			}
			patientInfoMapper.updatePatientInfo(patientInfo);
		}
        return preHospitalizationMapper.deleteByIds(ids);
    }

    @Override
    public PatientPreHospitalization getById(Long id) {
        return preHospitalizationMapper.selectByPrimaryKey(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult importList(List<PatientPreHospitalization> patientList) {
        //判断添加的数据是否为空
        if (CollectionUtils.isEmpty(patientList)) {
            return AjaxResult.error("请添加预住院患者导入信息！");
        }
	    if (SecurityUtils.getLoginUser().getUser().getHospitalAgencyId() == null) {
		    return AjaxResult.error("您未设置机构信息，导入失败");
	    }
        // 根据患者身份证号做去重处理
        List<PatientPreHospitalization> importDataList = patientList.stream().filter(item -> StringUtils.isNotBlank(item.getCardNo())).distinct().collect(Collectors.toList());
        // 校验联系电话格式是否正确
        PatientPreHospitalization patient = importDataList.stream().filter(item -> StringUtils.isNotBlank(item.getPatientPhone())).filter(item -> BooleanUtils.isFalse(regexUtil.regexPhone(item.getPatientPhone()))).findFirst().orElse(new PatientPreHospitalization());
        if (StringUtils.isNotBlank(patient.getPatientPhone())) {
            return AjaxResult.error("当前患者联系电话：" + patient.getPatientPhone() + " 格式不正确，请重新录入！");
        }
        List<PatientPreHospitalization> saveList = new ArrayList<>();
        for (PatientPreHospitalization item : importDataList) {
            PatientPreHospitalization preHospitalization = new PatientPreHospitalization();
            BeanUtils.copyProperties(item, preHospitalization);
            // 设置机构/院区为当前登录用户机构信息
            preHospitalization.setHospitalAgencyId(SecurityUtils.getLoginUser().getUser().getHospitalAgencyId());
            Agency agencyData = agencyMapper.selectAgencyById(SecurityUtils.getLoginUser().getUser().getHospitalAgencyId());
            if (ObjectUtils.isNotEmpty(agencyData)) {
	            if (StringUtils.equals(NodeTypeConstants.HOSPITAL, agencyData.getNodeType())) { // 节点类型为机构
		            preHospitalization.setHospitalAgencyName(agencyData.getAgencyName());
	            } else if (StringUtils.equals(NodeTypeConstants.CAMPUS, agencyData.getNodeType())) { // 节点类型为院区
					preHospitalization.setCampusAgencyId(agencyData.getId());
		            preHospitalization.setCampusAgencyName(agencyData.getAgencyName());
					// 机构设为院区所属机构
		            preHospitalization.setHospitalAgencyId(agencyData.getParentId());
		            Agency agency = agencyMapper.selectAgencyById(agencyData.getParentId());
		            preHospitalization.setHospitalAgencyName(agency.getAgencyName());
	            }
            }

            // 查询科室id
            Department department = new Department();
            if (StringUtils.isNotBlank(item.getDepartmentName())) {
                department.setHospitalAgencyName(preHospitalization.getHospitalAgencyName());
                department.setDepartmentName(item.getDepartmentName());
                department.setNodeType(NodeTypeConstants.DEPARTMENT);
                List<Department> deptList = departmentMapper.selectDepartmentList(department);
                if (CollectionUtils.isNotEmpty(deptList)) {
                    preHospitalization.setDepartmentId(deptList.get(0).getId());
                }
            }
            // 查询病区
            if (StringUtils.isNotBlank(item.getWardName())) {
                department.setHospitalAgencyName(item.getHospitalAgencyName());
                department.setDepartmentName(item.getWardName());
                department.setNodeType(NodeTypeConstants.WARD);
                List<Department> deptList = departmentMapper.selectDepartmentList(department);
                if (CollectionUtils.isNotEmpty(deptList)) {
                    preHospitalization.setWardId(deptList.get(0).getId());
                }
            }

	        preHospitalization.setDelFlag(0);
            preHospitalization.setCreateTime(LocalDateTime.now());
            preHospitalization.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());

            // 根据身份证号+机构id查询患者信息
            PatientInfoDto patientQuery = new PatientInfoDto();
            patientQuery.setCardNo(item.getCardNo());
	        patientQuery.setHospitalAgencyId(preHospitalization.getHospitalAgencyId());
            List<PatientInfo> patientInfoList = patientInfoService.selectAllPatientList(patientQuery);
            if (CollectionUtils.isNotEmpty(patientInfoList)) {
                // 修改居民信息
                PatientInfo updInfo = patientInfoList.get(0);
                String[] ignore = {"id"};
				BeanUtils.copyProperties(preHospitalization,updInfo, ignore);
	            updInfo.setVisitDate(preHospitalization.getRegistrationDate().atStartOfDay());
	            updInfo.setPatientType(PatientTypeConstants.PRE_HOSPITALIZED_PATIENT);
	            patientInfoService.updatePatientInfo(updInfo);
                preHospitalization.setPatientId(updInfo.getId());
	            preHospitalization.setResidentId(updInfo.getResidentId());
            } else {
                PatientInfo saveInfo = new PatientInfo();
                // 添加居民
                BeanUtils.copyProperties(preHospitalization, saveInfo);
	            saveInfo.setVisitDate(preHospitalization.getRegistrationDate().atStartOfDay());
	            saveInfo.setPatientType(PatientTypeConstants.PRE_HOSPITALIZED_PATIENT);
	            PatientInfo patientInfo = patientInfoService.insertPatientInfo(saveInfo);
                preHospitalization.setPatientId(patientInfo.getId());
	            preHospitalization.setResidentId(patientInfo.getResidentId());
            }
            // 根据患者身份证号和预约时间查询是否有记录
            PatientPreHospitalization preHospitalizationQuery = new PatientPreHospitalization();
	        preHospitalizationQuery.setHospitalAgencyId(preHospitalization.getHospitalAgencyId());
            preHospitalizationQuery.setCardNo(item.getCardNo());
            preHospitalizationQuery.setAppointmentDate(item.getAppointmentDate());
            List<PatientPreHospitalization> list = preHospitalizationMapper.selectApplyList(preHospitalizationQuery);
            if (CollectionUtils.isEmpty(list)) {
                // 新增
                saveList.add(preHospitalization);
            } else {
                // 有预约信息暂时不导入
            }
        }
        int insertCount = preHospitalizationMapper.insertBatch(saveList);
        if (insertCount <= 0) {
            throw new ServiceException("导入预住院信息失败，请联系管理员！");
        }
        return AjaxResult.success();
    }

	private void setPreHospitalizationInfoNull(PatientInfo patientInfo) {
		patientInfo.setAppointmentDate(null);
		patientInfo.setAppointmentTreatmentGroup(null);
		patientInfo.setPatientType(null);
	}
}
