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

import com.xinelu.common.annotation.DataScope;
import com.xinelu.common.constant.SignRecordServiceStatusConstants;
import com.xinelu.common.constant.VisitMethodConstants;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.core.domain.entity.SysUser;
import com.xinelu.common.enums.ImportStatusEnum;
import com.xinelu.common.enums.PatientSourceEnum;
import com.xinelu.common.enums.PatientTypeEnum;
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.patientinfoimport.PatientInfoImport;
import com.xinelu.manage.domain.patientinfoimportmain.PatientInfoImportMain;
import com.xinelu.manage.domain.patientvisitrecord.PatientVisitRecord;
import com.xinelu.manage.domain.residentinfo.ResidentInfo;
import com.xinelu.manage.domain.signpatientrecord.SignPatientRecord;
import com.xinelu.manage.dto.patientinfo.PatientBaseInfoDto;
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.patientinfoimport.PatientInfoImportMapper;
import com.xinelu.manage.mapper.patientinfoimportmain.PatientInfoImportMainMapper;
import com.xinelu.manage.mapper.patientvisitrecord.PatientVisitRecordMapper;
import com.xinelu.manage.mapper.residentinfo.ResidentInfoMapper;
import com.xinelu.manage.mapper.signpatientrecord.SignPatientRecordMapper;
import com.xinelu.manage.service.patientinfo.IPatientInfoService;
import com.xinelu.manage.service.patientvisitrecord.IPatientVisitRecordService;
import com.xinelu.manage.vo.patientinfo.PatientImportVo;
import com.xinelu.manage.vo.patientinfo.PatientInfoVo;
import com.xinelu.manage.vo.patientinfoimport.DeptAliasVO;
import com.xinelu.manage.vo.patientinfoimport.PatientInfoImportVO;
import com.xinelu.system.mapper.SysUserMapper;
import com.xinelu.system.service.ISysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 患者信息Service业务层处理
 *
 * @author haown
 * @date 2024-02-26
 */
@Slf4j
@Service
public class PatientInfoServiceImpl implements IPatientInfoService {

    @Resource
    private PatientInfoMapper patientInfoMapper;
    @Resource
    private ResidentInfoMapper residentInfoMapper;
    @Resource
    private IPatientVisitRecordService patientVisitRecordService;
    @Resource
    private SignPatientRecordMapper signPatientRecordMapper;
    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private DepartmentMapper departmentMapper;
    @Resource
    private PatientInfoImportMapper patientInfoImportMapper;
    @Resource
    private PatientVisitRecordMapper patientVisitRecordMapper;
    @Resource
    private RegexUtil regexUtil;
    @Resource
    private PatientInfoImportMainMapper patientInfoImportMainMapper;
    @Resource
    private AgencyMapper agencyMapper;
    @Resource
    private ISysConfigService sysConfigService;

    /**
     * 查询患者信息
     *
     * @param id 患者信息主键
     * @return 患者信息
     */
    @Override
    public PatientInfo selectPatientInfoById(Long id) {
        return patientInfoMapper.selectPatientInfoById(id);
    }

    /**
     * 查询患者信息列表
     *
     * @param patientInfo 患者信息
     * @return 患者信息
     */
    @Override
    @DataScope(agencyAlias = "p", userAlias = "p.attending_physician_id")
    public List<PatientInfo> selectPatientInfoList(PatientInfoDto patientInfo) {
        return patientInfoMapper.selectPatientInfoList(patientInfo);
    }

    /**
     * @param patientInfo 患者信息查询传输对象
     * @return 患者信息集合
     * @description 患者管理——患者档案列表
     * @Author haown
     * @Date 2024-08-05 14:46
     */
    @DataScope(agencyAlias = "p", userAlias = "p.attending_physician_id")
    @Override
    public List<PatientInfoVo> getPatientList(PatientInfoDto patientInfo) {
        List<PatientInfoVo> patientInfoVoList = patientInfoMapper.getPatientList(patientInfo);
        return patientInfoVoList;
    }

    /**
     * 查询患者信息列表
     *
     * @param patientInfo 患者信息
     * @return 患者信息
     */
    @Override
    public List<PatientInfo> selectAllPatientList(PatientInfoDto patientInfo) {
        return patientInfoMapper.selectPatientInfoList(patientInfo);
    }

    /**
     * 新增患者信息
     *
     * @param patientInfo 患者信息
     * @return 结果
     */
    @Override
    @Transactional
    public PatientInfo insertPatientInfo(PatientInfo patientInfo) {
        if (StringUtils.isBlank(patientInfo.getCardNo())) {
            throw new ServiceException("请输入身份证号");
        }
        // 根据身份证号+机构id判断用户信息是否存在
        PatientInfoDto patientQuery = new PatientInfoDto();
        patientQuery.setCardNo(patientInfo.getCardNo());
        patientQuery.setHospitalAgencyId(patientInfo.getHospitalAgencyId());
        List<PatientInfo> patientList = patientInfoMapper.selectPatientInfoList(patientQuery);
        boolean exist = false;
        if (CollectionUtils.isNotEmpty(patientList)) {
            PatientInfo patientOld = patientList.get(0);
            patientInfo.setId(patientOld.getId());
            exist = true;
        } else {
            patientInfo.setCreateTime(LocalDateTime.now());
            patientInfo.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
        }
        patientInfo.setDelFlag(0);
        // 根据身份证号计算性别出生日期
        if (patientInfo.getBirthDate() == null) {
            patientInfo.setBirthDate(BaseUtil.getBirthday(patientInfo.getCardNo()));
        }
        if (StringUtils.isBlank(patientInfo.getSex())) {
            patientInfo.setSex(BaseUtil.getGender(patientInfo.getCardNo()));
        }
        // 先根据身份证号查询是否有该居民
        ResidentInfo residentQuery = new ResidentInfo();
        residentQuery.setCardNo(patientInfo.getCardNo());
        List<ResidentInfo> residentList = residentInfoMapper.selectResidentInfoList(residentQuery);
        // 身份证号没查到居民，通过手机号查询居民
        if (CollectionUtils.isEmpty(residentList) && StringUtils.isNotBlank(patientInfo.getPatientPhone())) {
            residentQuery.setCardNo(null);
            residentQuery.setPatientPhone(patientInfo.getPatientPhone());
            residentList = residentInfoMapper.selectResidentInfoList(residentQuery);
        }
        ResidentInfo residentInfo = new ResidentInfo();
        BeanUtils.copyBeanProp(residentInfo, patientInfo);
        if (CollectionUtils.isEmpty(residentList)) {
            // 新增居民
            residentInfoMapper.insertResidentInfo(residentInfo);
            patientInfo.setResidentId(residentInfo.getId());
        } else {
            // 修改居民信息
            residentInfo.setId(residentList.get(0).getId());
            residentInfoMapper.updateResidentInfo(residentInfo);
            patientInfo.setResidentId(residentList.get(0).getId());
        }
        // 患者来源
        if (StringUtils.isBlank(patientInfo.getPatientSource())) {
            patientInfo.setPatientSource(PatientSourceEnum.MANAGE_END.name());
        }
        if (exist) {
            patientInfoMapper.updatePatientInfoSelective(patientInfo);
        } else {
            patientInfoMapper.insertPatientInfo(patientInfo);
        }
        return patientInfo;
    }

    /**
     * 修改患者信息
     *
     * @param patientInfo 患者信息
     * @return 结果
     */
    @Override
    public PatientInfo updatePatientInfo(PatientInfo patientInfo) {
        if (StringUtils.isBlank(patientInfo.getCardNo())) {
            throw new ServiceException("请输入身份证号");
        }
        // 根据身份证号计算性别出生日期
        patientInfo.setBirthDate(BaseUtil.getBirthday(patientInfo.getCardNo()));
        patientInfo.setSex(BaseUtil.getGender(patientInfo.getCardNo()));
        ResidentInfo residentInfo = new ResidentInfo();
        if (patientInfo.getResidentId() != null) {
            residentInfo = residentInfoMapper.selectResidentInfoById(patientInfo.getResidentId());
            BeanUtils.copyBeanProp(residentInfo, patientInfo);
            residentInfo.setId(patientInfo.getResidentId());
            residentInfoMapper.updateResidentInfo(residentInfo);
        } else {
            // 先根据身份证号查询是否有该居民
            ResidentInfo residentQuery = new ResidentInfo();
            residentQuery.setCardNo(patientInfo.getCardNo());
            List<ResidentInfo> residentList = residentInfoMapper.selectResidentInfoList(residentQuery);
            // 身份证号没查到居民，通过手机号查询居民
            if (CollectionUtils.isEmpty(residentList) && StringUtils.isNotBlank(patientInfo.getPatientPhone())) {
                residentQuery.setCardNo(null);
                residentQuery.setPatientPhone(patientInfo.getPatientPhone());
                residentList = residentInfoMapper.selectResidentInfoList(residentQuery);
            }
            if (CollectionUtils.isNotEmpty(residentList)) {
                Long residentId = residentList.get(0).getId();
                residentInfo = residentList.get(0);
                BeanUtils.copyBeanProp(residentInfo, patientInfo);
                residentInfo.setId(residentId);
                residentInfoMapper.updateResidentInfo(residentInfo);
            } else {
                BeanUtils.copyBeanProp(residentInfo, patientInfo);
                residentInfo.setId(null);
                residentInfoMapper.insertResidentInfo(residentInfo);
            }
            patientInfo.setResidentId(residentInfo.getId());
        }
        patientInfo.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName());
        patientInfo.setUpdateTime(LocalDateTime.now());
        patientInfo.setDelFlag(0);
        patientInfoMapper.updatePatientInfoSelective(patientInfo);
        return patientInfo;
    }

    @Override
    public PatientInfo updateBaseInfo(PatientBaseInfoDto patientInfo) {
        PatientInfo patientInfo1 = patientInfoMapper.selectPatientInfoById(patientInfo.getId());
        BeanUtils.copyBeanProp(patientInfo1, patientInfo);
        return updatePatientInfo(patientInfo1);
    }

    /**
     * 批量删除患者信息
     *
     * @param ids 需要删除的患者信息主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deletePatientInfoByIds(Long[] ids) {
        int flag = 0;
        for (Long id : ids) {
            PatientInfo patientInfo = patientInfoMapper.selectPatientInfoById(id);
            // 查询关联的就诊记录是否已签约
            if (patientInfo.getSignPatientRecordId() != null && StringUtils.equals(SignRecordServiceStatusConstants.SERVICE_CENTER, patientInfo.getServiceStatus())) {
                SignPatientRecord signPatientRecord = signPatientRecordMapper.selectByPrimaryKey(patientInfo.getSignPatientRecordId());
                if (ObjectUtils.isNotEmpty(signPatientRecord) && Objects.equals(patientInfo.getPatientVisitRecordId(), signPatientRecord.getPatientVisitRecordId()) && signPatientRecord.getDelFlag() == 0) {
                    throw new ServiceException("该居民已签约不能删除该就诊记录！");
                }
            }
            patientVisitRecordService.deletePatientVisitRecordById(patientInfo.getPatientVisitRecordId());
            // 根据患者最新一条就诊记录修改患者状态
            PatientVisitRecordDto patientVisitRecordDto = new PatientVisitRecordDto();
            patientVisitRecordDto.setHospitalAgencyId(patientInfo.getHospitalAgencyId());
            patientVisitRecordDto.setPatientId(id);
            PatientVisitRecord patientVisitRecord = patientVisitRecordService.getLastRecord(patientVisitRecordDto);
            if (ObjectUtils.isEmpty(patientVisitRecord)) {
                setVisitInfoNull(patientInfo);
            } else {
                BeanUtils.copyBeanProp(patientInfo, patientVisitRecord);
                patientInfo.setId(id);
                patientInfo.setPatientVisitRecordId(patientVisitRecord.getId());
                // 设置patientType
                patientVisitRecordService.setPatientType(patientInfo, patientVisitRecord);
            }
            patientInfo.setPatientType(null);
            flag += patientInfoMapper.updatePatientInfo(patientInfo);
        }
        return flag;
    }

    /**
     * 设置患者就诊信息为空
     *
     * @param patientInfo 患者信息
     */
    private void setVisitInfoNull(PatientInfo patientInfo) {
        patientInfo.setVisitDate(null);
        patientInfo.setPatientType(null);
        patientInfo.setPatientVisitRecordId(null);
        patientInfo.setVisitMethod(null);
        patientInfo.setAdmissionTime(null);
        patientInfo.setDischargeTime(null);
        patientInfo.setAttendingPhysicianId(null);
        patientInfo.setAttendingPhysicianName(null);
        patientInfo.setResponsibleNurse(null);
        patientInfo.setMainDiagnosis(null);
        patientInfo.setVisitSerialNumber(null);
        patientInfo.setInHospitalNumber(null);
    }

    /**
     * 删除患者信息
     *
     * @param id 患者信息主键
     * @return 结果
     */
    @Override
    public int deletePatientInfoById(Long id) {
        return patientInfoMapper.deletePatientInfoById(id);
    }

    /**
     * 患者导入
     *
     * @param list 患者信息集合
     *             isDistinct==1，表示自动去重；==0表示不去重；
     *             fileName,附件名称；
     * @return AjaxResult
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult patientUpload(List<PatientInfoImport> list, Integer isDistinct, String fileName ,String importName) {
        int number;
        String importPersonTime = sysConfigService.selectConfigByKey("import_person_time");
        if (org.apache.commons.lang3.StringUtils.isBlank(importPersonTime) || importPersonTime.equals("")) {
            number = 1000;
        }
        number = Integer.parseInt(importPersonTime);
        if (CollectionUtils.isNotEmpty(list) && list.size() > number) {
            return AjaxResult.error("本次导入表数据超过" + number + "人次上限！");
        }
        PatientInfoImport patientInfoImport1 = new PatientInfoImport();
        patientInfoImport1.setCreateTime(LocalDateTime.now());
        List<PatientInfoImport> patientInfoImports = patientInfoImportMapper.selectPatientInfoImportList(patientInfoImport1);
        if (CollectionUtils.isNotEmpty(patientInfoImports) && patientInfoImports.size() > number) {
            return AjaxResult.error("今日导入已达" + number + "人次上限！");
        }
        if (CollectionUtils.isNotEmpty(list) && CollectionUtils.isNotEmpty(patientInfoImports) && (list.size() + patientInfoImports.size() > number)) {
            return AjaxResult.error("总计导入超过" + number + "人次上限，请修改后重新导入！");
        }
        //登录用户科室信息
        SysUser sysUser = sysUserMapper.selectUserById(SecurityUtils.getUserId());
        Agency agency = agencyMapper.selectAgencyById(sysUser.getHospitalAgencyId());
        if (Objects.isNull(agency) || StringUtils.isEmpty(agency.getNodeType())) {
            return AjaxResult.error("该账号无所属医院信息，请先配置该账号所属的医院信息！");
        }
        //如果要导入的数据列表为空，直接返回
        if (CollectionUtils.isEmpty(list) || list.size() == 0) {
            return AjaxResult.error("导入数据列表不能为空!");
        }
        //如果存在 患者姓名或手机号或科室或就诊日期为空的情况，直接返回；（暂时去除时间判断）
        List<PatientInfoImport> collect = list.stream().filter(Objects::nonNull).filter(item -> StringUtils.isEmpty(item.getPatientName())).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(collect)) {
            return AjaxResult.error("用户信息不完整，姓名均不允许为空，请完善后重试；");
        }
        //存在手机号格式不正确的情况，直接返回
//        List<PatientInfoImport> regexPhoneList = list.stream().filter(item -> StringUtils.isNotBlank(item.getPatientPhone())).filter(item -> BooleanUtils.isFalse(regexUtil.regexPhone(item.getPatientPhone()))).collect(Collectors.toList());
//        if (CollectionUtils.isNotEmpty(regexPhoneList)) {
//            return AjaxResult.error(HttpStatus.ERROR_TWO, "部分手机号格式不正确，请修改后重试；", regexPhoneList);
//        }
        //导入重复过滤，列表内患者信息自去重；
        List<PatientInfoImport> distinctCollect = list.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
        //与数据库重复（当天数据）
        List<PatientInfo> patientInfos_CurrentDay = new ArrayList<>();
        List<ResidentInfo> residentInfos = residentInfoMapper.selectResidentInfoByPhoneList(list);
        //如果要求自动去重（同数据库中 当日已导入患者列表 比对，如果患者姓名和手机号相同，视为重复）
        if (Objects.isNull(isDistinct) || isDistinct == 1) {
            LocalDate nowDate = LocalDate.now();
            //此处实现是当天跟患者表数据比对，（也可以直接跟已导入患者表数据比对）
            patientInfos_CurrentDay = patientInfoMapper.selectPatientInfoByPatientName(list, nowDate);
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        //获得本月第一天
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        String firstDay = sdf.format(calendar.getTime());
        //获得本月最后一天
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        String lastDay = sdf.format(calendar.getTime());
        List<PatientImportVo> patientInfoList = patientInfoMapper.selectPatientInfoByTime(list, firstDay, lastDay);
        //sn  导入流水号；
        String sn = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));

        Department department = new Department();
        department.setHospitalAgencyId(sysUser.getHospitalAgencyId());
        List<Department> departmentList = departmentMapper.selectDepartmentNameCount(department);

        PatientInfoImportVO patientInfoImportVO = new PatientInfoImportVO();
        List<DeptAliasVO> deptAliasVOS = new ArrayList<>();
        //组装数据
        List<PatientInfoImport> patientInfoImportList = new ArrayList<>();
        //要导入的居民信息列表
        List<PatientInfoImport> patientInfoImportList_forResident = new ArrayList<>();
        String aiobMaxCount = sysConfigService.selectConfigByKey("aiob_max_count");
        for (PatientInfoImport patientInfoImport : distinctCollect) {
            //选择自动去除当日重复记录
            // if (CollectionUtils.isNotEmpty(residentInfos)) {
            //     List<ResidentInfo> collect1 = residentInfos.stream().filter(Objects::nonNull).filter(item -> patientInfoImport.getPatientName().equals(item.getPatientName()) && patientInfoImport.getPatientPhone().equals(item.getPatientPhone())).collect(Collectors.toList());
            //     if (CollectionUtils.isNotEmpty(collect1)) {
            //         continue;
            //     }
            // }
            // 如果当日已有导入，则不再重复导入（导入数据存在手机号为空）
            if (CollectionUtils.isNotEmpty(patientInfos_CurrentDay) && (Objects.isNull(isDistinct) || isDistinct == 1) && org.apache.commons.lang3.StringUtils.isNotBlank(patientInfoImport.getPatientPhone())) {
                List<PatientInfo> collect1 = patientInfos_CurrentDay.stream().filter(Objects::nonNull).filter(item -> patientInfoImport.getPatientName().equals(item.getPatientName()) && patientInfoImport.getPatientPhone().equals(item.getPatientPhone())).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(collect1) || collect1.size() != 0) {
                    continue;
                }
            }
            //同一手机号每月可最多拔打xx次
            if (CollectionUtils.isNotEmpty(patientInfoList) && StringUtils.isNotBlank(aiobMaxCount) && org.apache.commons.lang3.StringUtils.isNotBlank(patientInfoImport.getPatientPhone())) {
                List<PatientInfo> collect1 = patientInfoList.stream().filter(Objects::nonNull).filter(item -> patientInfoImport.getPatientPhone().equals(item.getPatientPhone()) && item.getCountPhone() >= Long.parseLong(aiobMaxCount)).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(collect1) || collect1.size() != 0) {
                    continue;
                }
            }
            //判断是否有科室名称或别名一致
            patientInfoImport.setSn(sn);
            patientInfoImport.setCreateBy(SecurityUtils.getUsername());
            patientInfoImport.setCreateTime(LocalDateTime.now());
            patientInfoImport.setHospitalAgencyId(agency.getId());
            patientInfoImport.setHospitalAgencyName(agency.getAgencyName());
            //医院有科室且名称一致塞值，不一致不动
            if (CollectionUtils.isNotEmpty(departmentList)) {
                Department equalsDepartment = departmentList.stream().filter(Objects::nonNull).filter(item -> patientInfoImport.getDeptAlias().equals(item.getDepartmentName())).findFirst().orElse(new Department());
                //科室名称一致塞值
                if (Objects.nonNull(equalsDepartment.getId())) {
                    patientInfoImport.setDepartmentId(equalsDepartment.getId());
                    patientInfoImport.setDepartmentName(equalsDepartment.getDepartmentName());
                    patientInfoImportList.add(patientInfoImport);
                    continue;
                    //科室别名一致塞值
                } else {
                    Department containsDepartment = departmentList.stream().filter(Objects::nonNull).filter(item -> StringUtils.isNotEmpty(item.getDepartmentAbbreviation()) && item.getDepartmentAbbreviation().contains(patientInfoImport.getDeptAlias())).findFirst().orElse(new Department());
                    if (Objects.nonNull(containsDepartment.getId())) {
                        List<String> departmentAbbreviation = Arrays.asList(containsDepartment.getDepartmentAbbreviation().split("\\|"));
                        String s = departmentAbbreviation.stream().filter(Objects::nonNull).filter(item -> (patientInfoImport.getDeptAlias().equals(item))).findFirst().orElse(null);
                        if (StringUtils.isNotBlank(s)) {
                            patientInfoImport.setDepartmentId(containsDepartment.getId());
                            patientInfoImport.setDepartmentName(containsDepartment.getDepartmentName());
                            patientInfoImportList.add(patientInfoImport);
                            continue;
                        }
                    }
                }
            }
            //无科室名返回数据
            DeptAliasVO deptAliasVO = new DeptAliasVO();
            deptAliasVO.setSn(sn);
            deptAliasVO.setDeptAlias(patientInfoImport.getDeptAlias());
            deptAliasVOS.add(deptAliasVO);
            // patientInfoImportList为总数据,新增patient_info_import需要
            patientInfoImport.setDepartmentName(patientInfoImport.getDeptAlias());
            patientInfoImportList.add(patientInfoImport);
        }
        if (CollectionUtils.isEmpty(patientInfoImportList)) {
            return AjaxResult.success("附件中所有患者记录与今日已导入数据重复，不能重复导入");
        }
        //组装返回科室数据
        patientInfoImportVO.setSn(sn);
        patientInfoImportVO.setCount(list.size());
        if (CollectionUtils.isNotEmpty(departmentList) && departmentList.size() > 0) {
            patientInfoImportVO.setDepartments(departmentList);
        }
        if (CollectionUtils.isNotEmpty(deptAliasVOS)) {
            deptAliasVOS = deptAliasVOS.stream().filter(Objects::nonNull).filter(item -> Objects.nonNull(item.getDeptAlias())).distinct().collect(Collectors.toList());
            patientInfoImportVO.setDeptAliasVOS(deptAliasVOS);
        }

        //新增缓存表
        int insertCount = patientInfoImportMapper.insertPatientInfoImportList(patientInfoImportList);
        if (insertCount <= 0) {
            log.info("缓存表新增失败！");
            return AjaxResult.error("数据导入失败！");
        }
        //region 导入记录主表
        PatientInfoImportMain patientInfoImportMain = new PatientInfoImportMain();
        patientInfoImportMain.setCreateBy(SecurityUtils.getUsername());
        patientInfoImportMain.setCreateTime(LocalDateTime.now());
        patientInfoImportMain.setSn(sn);
        patientInfoImportMain.setHospitalAgencyId(agency.getId());
        patientInfoImportMain.setFileName(fileName);
        patientInfoImportMain.setHospitalAgencyName(agency.getAgencyName());
        patientInfoImportMain.setImportStatus(ImportStatusEnum.UNFINISHED.getInfo());
        patientInfoImportMain.setImportName(org.apache.commons.lang3.StringUtils.isNotBlank(importName)?importName : sn);
        patientInfoImportMainMapper.insertPatientInfoImportMain(patientInfoImportMain);
        //endregion

        //科室名称全符合新增患者表，否则返回数据  （简化导入修改）
        //if (CollectionUtils.isNotEmpty(deptAliasVOS)) {
            //return AjaxResult.error("科室名称不存在", patientInfoImportVO);
        //}
        //region 新增居民表
        patientInfoImportList.forEach(item ->
                {
                    //设置导入记录ID
                    item.setPatientInfoImportId(item.getId());
                    if (org.apache.commons.lang3.StringUtils.isNotBlank(item.getPatientPhone())) {
                        //居民信息去重
                        if (residentInfos.stream().filter(residentInfo -> residentInfo.getPatientName().equals(item.getPatientName())
                                && residentInfo.getPatientPhone().equals(item.getPatientPhone())).collect(Collectors.toSet()).size() == 0) {
                            patientInfoImportList_forResident.add(item);
                        }
                        //如果已存在
                        else {
                            //设置居民ID
                            item.setResidentId(residentInfos.stream().filter(residentInfo -> residentInfo.getPatientName().equals(item.getPatientName())
                                    && residentInfo.getPatientPhone().equals(item.getPatientPhone())).findFirst().orElse(new ResidentInfo()).getId());
                        }
                    } else {
                        patientInfoImportList_forResident.add(item);
                    }
                }
        );
        if (patientInfoImportList_forResident.size() > 0) {
            int residentCount = residentInfoMapper.insertResidentInfoList(patientInfoImportList_forResident);
            if (residentCount <= 0) {
                log.info("居民表新增失败！");
                return AjaxResult.error("居民信息新增失败；");
            }
            patientInfoImportList_forResident.forEach(item ->
                    {
                        patientInfoImportList.stream().filter(item2 -> item2.getPatientName().equals(item.getPatientName())
                                        && (item2.getPatientPhone() == null ? ' ' : item2.getPatientPhone()).equals((item.getPatientPhone() == null ? ' ' : item.getPatientPhone()))).findFirst().orElse(new PatientInfoImport())
                                .setResidentId(item.getId());
                    }
            );
        }
        //endregion

            //设置为门诊患者
            patientInfoImportList.forEach(item ->
            {
                item.setPatientType(PatientTypeEnum.OUTPATIENT.getInfo());
                item.setVisitMethod(VisitMethodConstants.OUTPATIENT_SERVICE);
            });
            //新增患者表
            int insertPatientInfo = patientInfoMapper.insertPatientInfoList(patientInfoImportList);
            if (insertPatientInfo <= 0) {
                log.info("患者表新增失败！");
                return AjaxResult.error("患者信息新增失败；");
            }
            patientInfoImportList.forEach(item -> item.setPatientInfoId(item.getId()));
            //新增就诊记录表
            //region 新增就诊记录表
            List<PatientVisitRecord> patientVisitRecords = new ArrayList<>();
            for (PatientInfoImport patientInfoImport : patientInfoImportList) {
                PatientVisitRecord patientVisitRecord = new PatientVisitRecord();
                patientVisitRecord.setPatientId(patientInfoImport.getPatientInfoId());
                patientVisitRecord.setResidentId(patientInfoImport.getResidentId());
                BeanUtils.copyProperties(patientInfoImport, patientVisitRecord);
                patientVisitRecord.setDelFlag(0);
                patientVisitRecord.setHospitalAgencyId(agency.getId());
                patientVisitRecord.setHospitalAgencyName(agency.getAgencyName());
                patientVisitRecord.setCreateBy(SecurityUtils.getUsername());
                patientVisitRecord.setCreateTime(LocalDateTime.now());
                patientVisitRecord.setVisitDate(patientInfoImport.getVisitDate().atTime(0, 0, 0));
                patientVisitRecords.add(patientVisitRecord);
            }
            int patientVisitRecordCount = patientVisitRecordMapper.insertPatientVisitRecordList(patientVisitRecords);
            if (patientVisitRecordCount <= 0) {
                log.info("就诊记录表新增失败！");
                return AjaxResult.error("就诊记录新增失败");
            }
            // 更新 患者信息表中 的  最近一次问诊记录id
            for (PatientInfoImport patientInfoImport : patientInfoImportList) {
                //获取患者的最近一次就诊ID
                PatientVisitRecordDto patientVisitRecordDto = new PatientVisitRecordDto();
                patientVisitRecordDto.setPatientId(patientInfoImport.getPatientInfoId());
                PatientVisitRecord patientVisitRecord = patientVisitRecordMapper.getLastRecord(patientVisitRecordDto);
                PatientInfo patientInfo = new PatientInfo();
                patientInfo.setId(patientInfoImport.getPatientInfoId());
                // 修改患者最近一次就诊记录id
                patientInfo.setPatientVisitRecordId(patientVisitRecord.getId());
                patientInfoMapper.updatePatientInfoSelective(patientInfo);
            }
            //endregion

        PatientInfoImportMain patientInfoImportMainSn = new PatientInfoImportMain();
        patientInfoImportMainSn.setSn(sn);
        patientInfoImportMainSn.setImportStatus(ImportStatusEnum.FINISHED.getInfo());
        patientInfoImportMainMapper.updatePatientInfoImportMainImportStatus(patientInfoImportMainSn);
        String msg = "已完成数据导入！导入成功" + patientInfoImportList.size() + "条记录，失败0条记录";
        if (list.size() != patientInfoImportList.size()) {
            int i = list.size() - patientInfoImportList.size();
            msg = msg + "，重复" + i + "条记录（已自动去重）。";
        }
        return AjaxResult.success(msg);
    }

    /**
     * 未识别科室名称导入
     *
     * @param patientInfoImportVO 未识别科室集合
     * @return AjaxResult
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult secondaryUpload(PatientInfoImportVO patientInfoImportVO) {
        if (Objects.isNull(patientInfoImportVO) || CollectionUtils.isEmpty(patientInfoImportVO.getDeptAliasVOS()) || StringUtils.isEmpty(patientInfoImportVO.getSn())) {
            return AjaxResult.success();
        }
        //科室、医院
        SysUser sysUser = sysUserMapper.selectUserById(SecurityUtils.getUserId());
        Agency agency = agencyMapper.selectAgencyById(sysUser.getHospitalAgencyId());
        if (Objects.isNull(agency)) {
            return AjaxResult.error("已完成数据导入！导入成功0条记录，失败" + patientInfoImportVO.getCount() + "条记录。失败原因：该账号无所属医院信息，请先添加该账号所属的医院信息。");
        }
        Department department = new Department();
        department.setHospitalAgencyId(sysUser.getHospitalAgencyId());
        List<Department> departmentList = departmentMapper.selectDepartmentNameCount(department);
        if (CollectionUtils.isEmpty(departmentList)) {
            return AjaxResult.error("已完成数据导入！导入成功0条记录，失败" + patientInfoImportVO.getCount() + "条记录。失败原因：该账号所属医院无下级科室，请先维护所属医院的下级科室信息。");
        }
        //根据sn查询数据
        List<PatientInfoImport> patientInfoImports = patientInfoImportMapper.selectPatientInfoImportBySn(patientInfoImportVO.getSn());
        if (CollectionUtils.isEmpty(patientInfoImports)) {
            return AjaxResult.error("已完成数据导入！导入成功0条记录；失败" + patientInfoImportVO.getCount() + "条记录。");
        }
        List<PatientInfoImport> insertResidentInfo = new ArrayList<>();
        List<ResidentInfo> residentInfos = residentInfoMapper.selectResidentInfoByPhoneList(patientInfoImports);
        for (PatientInfoImport patientInfoImport : patientInfoImports) {
            if (StringUtils.isEmpty(patientInfoImport.getDepartmentName()) || Objects.isNull(patientInfoImport.getDepartmentId())) {
                DeptAliasVO deptAliasVO = patientInfoImportVO.getDeptAliasVOS().stream().filter(Objects::nonNull).filter(item -> StringUtils.isNotBlank(item.getDepartmentName()) && StringUtils.isNotEmpty(item.getDeptAlias()) && patientInfoImport.getDeptAlias().equals(item.getDeptAlias())).findFirst().orElse(new DeptAliasVO());
                Department equalsDepartment = departmentList.stream().filter(Objects::nonNull).filter(item -> item.getDepartmentName().equals(deptAliasVO.getDepartmentName())).findFirst().orElse(new Department());
                patientInfoImport.setDepartmentId(equalsDepartment.getId());
                patientInfoImport.setDepartmentName(equalsDepartment.getDepartmentName());
                //居民信息去重
                patientInfoImport.setPatientInfoImportId(patientInfoImport.getId());
                if (org.apache.commons.lang3.StringUtils.isNotBlank(patientInfoImport.getPatientPhone())) {
                    List<ResidentInfo> collect = residentInfos.stream().filter(residentInfo -> residentInfo.getPatientName().equals(patientInfoImport.getPatientName()) && residentInfo.getPatientPhone().equals(patientInfoImport.getPatientPhone())).collect(Collectors.toList());
                    if (CollectionUtils.isEmpty(collect) || collect.size() == 0) {
                        insertResidentInfo.add(patientInfoImport);
                    } else { //如果已存在 设置居民ID
                        patientInfoImport.setResidentId(residentInfos.stream().filter(residentInfo -> residentInfo.getPatientName().equals(patientInfoImport.getPatientName())
                                && residentInfo.getPatientPhone().equals(patientInfoImport.getPatientPhone())).findFirst().orElse(new ResidentInfo()).getId());
                    }
                } else {
                    insertResidentInfo.add(patientInfoImport);
                }
            }
        }
        //科室组装别名
        List<Department> departments = new ArrayList<>();
        for (Department department1 : departmentList) {
            Department deptAliasdepartment = new Department();
            List<String> collect = patientInfoImportVO.getDeptAliasVOS().stream().filter(Objects::nonNull).filter(item -> department1.getDepartmentName().equals(item.getDepartmentName())).map(DeptAliasVO::getDeptAlias).collect(Collectors.toList());
            String join = StringUtils.join(collect, "|");
            if (CollectionUtils.isNotEmpty(collect) && StringUtils.isNotEmpty(department1.getDepartmentAbbreviation())) {
                deptAliasdepartment.setDepartmentAbbreviation(department1.getDepartmentAbbreviation() + "|" + join);
                deptAliasdepartment.setId(department1.getId());
                deptAliasdepartment.setUpdateBy(SecurityUtils.getUsername());
                deptAliasdepartment.setUpdateTime(LocalDateTime.now());
                departments.add(deptAliasdepartment);
            } else if (CollectionUtils.isNotEmpty(collect) && StringUtils.isEmpty(department1.getDepartmentAbbreviation())) {
                deptAliasdepartment.setDepartmentAbbreviation(join);
                deptAliasdepartment.setId(department1.getId());
                deptAliasdepartment.setUpdateBy(SecurityUtils.getUsername());
                deptAliasdepartment.setUpdateTime(LocalDateTime.now());
                departments.add(deptAliasdepartment);
            }
        }
        //修改科室表别名信息
        if (CollectionUtils.isNotEmpty(departments)) {
            int i = departmentMapper.updateDepartmentListByIds(departments);
            if (i <= 0) {
                return AjaxResult.error("已完成数据导入！导入成功0条记录；失败" + patientInfoImportVO.getCount() + "条记录。");
            }
        }
        //新增居民表
        if (CollectionUtils.isNotEmpty(insertResidentInfo) || insertResidentInfo.size() != 0) {
            int residentCount = residentInfoMapper.insertResidentInfoList(insertResidentInfo);
            if (residentCount <= 0) {
                return AjaxResult.error("已完成数据导入！导入成功0条记录；失败" + patientInfoImportVO.getCount() + "条记录。");
            }
            insertResidentInfo.forEach(item -> {
                        patientInfoImports.stream().filter(patientInfoImport -> patientInfoImport.getPatientName().equals(item.getPatientName())
                                && (patientInfoImport.getPatientPhone() == null ? ' ' : patientInfoImport.getPatientPhone()).equals((item.getPatientPhone() == null ? ' ' : item.getPatientPhone()))).findFirst().orElse(new PatientInfoImport()).setResidentId(item.getId());
                    }
            );
        }
        //设置为门诊患者
        patientInfoImports.forEach(item -> {
            item.setPatientType(PatientTypeEnum.OUTPATIENT.getInfo());
            item.setVisitMethod(VisitMethodConstants.OUTPATIENT_SERVICE);
        });

        //新增患者表
        int i = patientInfoMapper.insertPatientInfoList(patientInfoImports);
        if (i <= 0) {
            return AjaxResult.error("已完成数据导入！导入成功0条记录；失败" + patientInfoImportVO.getCount() + "条记录。");
        }
        patientInfoImports.forEach(item -> item.setPatientInfoId(item.getId()));
        List<PatientVisitRecord> patientVisitRecords = new ArrayList<>();
        for (PatientInfoImport patientInfoImport : patientInfoImports) {
            PatientVisitRecord patientVisitRecord = new PatientVisitRecord();
            patientVisitRecord.setPatientId(patientInfoImport.getPatientInfoId());
            patientVisitRecord.setResidentId(patientInfoImport.getResidentId());
            BeanUtils.copyProperties(patientInfoImport, patientVisitRecord);
            patientVisitRecord.setDelFlag(0);
            patientVisitRecord.setHospitalAgencyId(agency.getId());
            patientVisitRecord.setHospitalAgencyName(agency.getAgencyName());
            patientVisitRecord.setCreateBy(SecurityUtils.getUsername());
            patientVisitRecord.setCreateTime(LocalDateTime.now());
            patientVisitRecords.add(patientVisitRecord);
        }
        int patientVisitRecordCount = patientVisitRecordMapper.insertPatientVisitRecordList(patientVisitRecords);
        if (patientVisitRecordCount <= 0) {
            return AjaxResult.error("已完成数据导入！导入成功0条记录；失败" + patientInfoImportVO.getCount() + "条记录。");
        }
        // 更新 患者信息表中 的  最近一次问诊记录id
        for (PatientInfoImport patientInfoImport : patientInfoImports) {
            //获取患者的最近一次就诊ID
            PatientVisitRecordDto patientVisitRecordDto = new PatientVisitRecordDto();
            patientVisitRecordDto.setPatientId(patientInfoImport.getPatientInfoId());
            PatientVisitRecord patientVisitRecord = patientVisitRecordMapper.getLastRecord(patientVisitRecordDto);
            PatientInfo patientInfo = new PatientInfo();
            patientInfo.setId(patientInfoImport.getPatientInfoId());
            // 修改患者最近一次就诊记录id
            patientInfo.setPatientVisitRecordId(patientVisitRecord.getId());
            patientInfoMapper.updatePatientInfoSelective(patientInfo);
        }
        //endregion
        PatientInfoImportMain patientInfoImportMainSn = new PatientInfoImportMain();
        patientInfoImportMainSn.setSn(patientInfoImportVO.getSn());
        patientInfoImportMainSn.setImportStatus(ImportStatusEnum.FINISHED.getInfo());
        patientInfoImportMainMapper.updatePatientInfoImportMainImportStatus(patientInfoImportMainSn);
        String msg = "已完成数据导入！导入成功" + patientInfoImports.size() + "条记录；失败0条记录";
        if (patientInfoImportVO.getCount() != patientInfoImports.size()) {
            int minus = patientInfoImportVO.getCount() - patientInfoImports.size();
            msg = msg + "，重复" + minus + "条记录（已自动去重）。";
        }
        return AjaxResult.success(msg);
    }
}
