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

import com.xinelu.common.annotation.DataScope;
import com.xinelu.common.config.XinELuConfig;
import com.xinelu.common.constant.Constants;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.core.domain.entity.SysUser;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.common.utils.codes.GenerateSystemCodeUtil;
import com.xinelu.common.utils.regex.RegexUtil;
import com.xinelu.manage.domain.hospitalpersoncertificate.HospitalPersonCertificate;
import com.xinelu.manage.domain.hospitalpersoninfo.HospitalPersonInfo;
import com.xinelu.manage.dto.hospitalpersoninfo.HospitalPersonInfoDTO;
import com.xinelu.manage.dto.hospitalpersoninfo.HospitalPersonInfoDtoo;
import com.xinelu.manage.mapper.hospitalpersoncertificate.HospitalPersonCertificateMapper;
import com.xinelu.manage.mapper.hospitalpersoninfo.HospitalPersonInfoMapper;
import com.xinelu.manage.mapper.nursestationperson.NurseStationPersonMapper;
import com.xinelu.manage.service.hospitalpersoninfo.IHospitalPersonInfoService;
import com.xinelu.manage.vo.hospitalpersoninfo.HospitalPersonInfoVO;
import com.xinelu.system.mapper.SysUserMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.File;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 健康咨询-科室人员信息Service业务层处理
 *
 * @author xinyilu
 * @date 2023-02-14
 */
@Service
public class HospitalPersonInfoServiceImpl implements IHospitalPersonInfoService {
    @Resource
    private HospitalPersonInfoMapper hospitalPersonInfoMapper;
    @Resource
    private GenerateSystemCodeUtil generateSystemCodeUtil;
    @Resource
    private RegexUtil regexUtil;
    @Resource
    private HospitalPersonCertificateMapper hospitalPersonCertificateMapper;
    @Resource
    private SysUserMapper userMapper;
    @Resource
    private NurseStationPersonMapper nurseStationPersonMapper;

    /**
     * 查询健康咨询-科室人员信息
     *
     * @param id 健康咨询-科室人员信息主键
     * @return 健康咨询-科室人员信息
     */
    @Override
    public HospitalPersonInfoVO selectHospitalPersonInfoById(Long id) {
        return hospitalPersonInfoMapper.selectHospitalPersonInfoById(id);
    }

    /**
     * 查询健康咨询-科室人员信息列表
     *
     * @param hospitalPersonInfo 健康咨询-科室人员信息
     * @return 健康咨询-科室人员信息
     */
    @Override
    @DataScope(deptAlias = "hpi", userAlias = "u")
    public List<HospitalPersonInfoVO> selectHospitalPersonInfoList(HospitalPersonInfoVO hospitalPersonInfo) {
        return hospitalPersonInfoMapper.selectHospitalPersonInfoList(hospitalPersonInfo);
    }

    @Override
    public List<HospitalPersonInfo> getList(HospitalPersonInfo hospitalPersonInfo) {
        return hospitalPersonInfoMapper.selectList(hospitalPersonInfo);
    }

    /**
     * 新增健康咨询-科室人员信息
     *
     * @param hospitalPersonInfo 健康咨询-科室人员信息
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertHospitalPersonInfo(HospitalPersonInfoDTO hospitalPersonInfo) {
        //校验联系电话是否正确
        if (Objects.nonNull(hospitalPersonInfo) && StringUtils.isNotBlank(hospitalPersonInfo.getPersonPhone())) {
            boolean phone = regexUtil.regexPhone(hospitalPersonInfo.getPersonPhone());
            if (BooleanUtils.isFalse(phone)) {
                return AjaxResult.error("您输入的联系电话" + hospitalPersonInfo.getPersonPhone() + "不正确，请重新输入！");
            }
            // 校验手机号是否重复
            int personPhoneCount = hospitalPersonInfoMapper.getPersonInfoByPhoneNumber(hospitalPersonInfo.getPersonPhone());
            if (personPhoneCount > 0) {
                return AjaxResult.error("您输入的联系电话" + hospitalPersonInfo.getPersonPhone() + "重复！");
            }
        }
        //校验身份证号是否正确
        if (Objects.nonNull(hospitalPersonInfo) && StringUtils.isNotBlank(hospitalPersonInfo.getCardNo())) {
            boolean phone = regexUtil.regexCardNo(hospitalPersonInfo.getCardNo());
            if (BooleanUtils.isFalse(phone)) {
                return AjaxResult.error("您输入的身份证号" + hospitalPersonInfo.getCardNo() + "不正确，请重新输入！");
            }
            //校验身份证号是否重复
            int cardNoByCount = hospitalPersonInfoMapper.selectHospitalPersonInfoByCount(hospitalPersonInfo.getCardNo());
            if (cardNoByCount > 0) {
                return AjaxResult.error("您输入的身份证号" + hospitalPersonInfo.getCardNo() + "重复，请重新添加！");
            }
        }
        if (StringUtils.equals("2", hospitalPersonInfo.getStatus()) && (Objects.isNull(hospitalPersonInfo.getConsultingFee()) || hospitalPersonInfo.getConsultingFee().compareTo(BigDecimal.ZERO) <= 0)) {
            return AjaxResult.error("咨询费用不能为0或者负数，请重新输入");
        }
        //创建人 创建时间 科室人员编码
        hospitalPersonInfo.setPersonCode(Constants.PERSON_CODE + generateSystemCodeUtil.generateSystemCode(Constants.PERSON_CODE));
        hospitalPersonInfo.setCreateTime(LocalDateTime.now());
        hospitalPersonInfo.setCreateBy(SecurityUtils.getUsername());
        int insertHospitalPersonInfo = hospitalPersonInfoMapper.insertHospitalPersonInfo(hospitalPersonInfo);
        if (insertHospitalPersonInfo <= 0) {
            throw new ServiceException("新增科室人员信息失败，请联系管理员！");
        }
        if (Objects.nonNull(hospitalPersonInfo.getHospitalPersonCertificateList())) {
            //新增科室人员资质证书表
            for (HospitalPersonCertificate hospitalPersonCertificate : hospitalPersonInfo.getHospitalPersonCertificateList()) {
                hospitalPersonCertificate.setHospitalPersonId(hospitalPersonInfo.getId());
                hospitalPersonCertificate.setCreateTime(LocalDateTime.now());
                hospitalPersonCertificate.setCreateBy(SecurityUtils.getUsername());
                hospitalPersonCertificate.setCertificateCode(Constants.CERTIFICATE_CODE + generateSystemCodeUtil.generateSystemCode(Constants.CERTIFICATE_CODE));
            }
            int hospitalPersonCertificates = hospitalPersonCertificateMapper.insertHospitalPersonCertificateList(hospitalPersonInfo.getHospitalPersonCertificateList());
            if (hospitalPersonCertificates <= 0) {
                throw new ServiceException("新增科室人员资质证书信息失败，请联系管理员！");
            }
        }
        // 判断用户名是否重复
        int count = userMapper.checkUserNameUnique(hospitalPersonInfo.getPersonAccount());
        if (count > 0) {
            throw new ServiceException("已存在用户名为" + hospitalPersonInfo.getPersonAccount() + "的用户，请重新输入用户名");
        }
        //保存到sys_user表，判断当前用户表中手机号是否存在，不存在再保存，存在不保存
        int nurseStationUserCount = nurseStationPersonMapper.getNurseStationUserCount(StringUtils.isBlank(hospitalPersonInfo.getPersonPhone()) ? "" : hospitalPersonInfo.getPersonPhone());
        if (nurseStationUserCount <= 0) {
            SysUser sysUser = new SysUser();
            sysUser.setUserName(hospitalPersonInfo.getPersonAccount());
            sysUser.setPassword(SecurityUtils.encryptPassword(hospitalPersonInfo.getPersonPassword()));
            sysUser.setNickName(hospitalPersonInfo.getPersonName());
            sysUser.setHospitalPersonId(hospitalPersonInfo.getId());
            sysUser.setHospitalId(hospitalPersonInfo.getHospitalId());
            sysUser.setPhonenumber(StringUtils.isBlank(hospitalPersonInfo.getPersonPhone()) ? "" : hospitalPersonInfo.getPersonPhone());
            sysUser.setStatus("0");
            sysUser.setDelFlag("0");
            userMapper.insertUser(sysUser);
        }
        return AjaxResult.success();
    }

    /**
     * 修改健康咨询-科室人员信息
     *
     * @param hospitalPersonInfo 健康咨询-科室人员信息
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updateHospitalPersonInfo(HospitalPersonInfoDTO hospitalPersonInfo) {
        //根据id查询当前人员是否存在
        HospitalPersonInfo personInfo = hospitalPersonInfoMapper.selectHospitalPersonInfoById(hospitalPersonInfo.getId());
        if (Objects.isNull(personInfo)) {
            return AjaxResult.error("当前科室人员信息不存在！");
        }
        AjaxResult ajaxResult = verificationHospital(hospitalPersonInfo, personInfo);
        if (Objects.nonNull(ajaxResult)) {
            return ajaxResult;
        }
        if (StringUtils.equals("2", hospitalPersonInfo.getStatus()) && (Objects.isNull(hospitalPersonInfo.getConsultingFee()) || hospitalPersonInfo.getConsultingFee().compareTo(BigDecimal.ZERO) <= 0)) {
            return AjaxResult.error("咨询费用不能为0或者负数，请重新输入");
        }
        //修改人 修改时间
        hospitalPersonInfo.setUpdateTime(LocalDateTime.now());
        hospitalPersonInfo.setUpdateBy(SecurityUtils.getUsername());
        hospitalPersonInfoMapper.updateHospitalPersonInfo(hospitalPersonInfo);
        // 修改sys_user表
        SysUser sysUser = new SysUser();
        sysUser.setHospitalPersonId(hospitalPersonInfo.getId());
        List<SysUser> userList = userMapper.selectUserList(sysUser);
        if (CollectionUtils.isEmpty(userList)) {
            // 判断用户名是否重复
            int count = userMapper.checkUserNameUnique(hospitalPersonInfo.getPersonAccount());
            if (count > 0) {
                throw new ServiceException("已存在用户名为" + hospitalPersonInfo.getPersonAccount() + "的用户，请重新输入用户名");
            }
            SysUser newUser = new SysUser();
            newUser.setUserName(hospitalPersonInfo.getPersonAccount());
            newUser.setPassword(SecurityUtils.encryptPassword(hospitalPersonInfo.getPersonPassword()));
            newUser.setNickName(hospitalPersonInfo.getPersonName());
            newUser.setHospitalPersonId(hospitalPersonInfo.getId());
            newUser.setHospitalId(hospitalPersonInfo.getHospitalId());
            newUser.setPhonenumber(StringUtils.isBlank(hospitalPersonInfo.getPersonPhone()) ? "" : hospitalPersonInfo.getPersonPhone());
            newUser.setStatus("0");
            newUser.setDelFlag("0");
            userMapper.insertUser(newUser);
        } else {
            // 修改用户信息
            SysUser updUser = userList.get(0);
            sysUser.setHospitalPersonId(hospitalPersonInfo.getId());
            updUser.setPassword(SecurityUtils.encryptPassword(hospitalPersonInfo.getPersonPassword()));
            updUser.setNickName(hospitalPersonInfo.getPersonName());
            updUser.setHospitalPersonId(hospitalPersonInfo.getId());
            updUser.setHospitalId(hospitalPersonInfo.getHospitalId());
            updUser.setPhonenumber(StringUtils.isBlank(hospitalPersonInfo.getPersonPhone()) ? "" : hospitalPersonInfo.getPersonPhone());
            updUser.setStatus("0");
            updUser.setDelFlag("0");
            userMapper.updateUser(updUser);
        }
        //根据科室人员id去查询对应的资质证书 使用流来获取所有的证书路径
        List<HospitalPersonCertificate> hospitalPersonCertificateList = hospitalPersonCertificateMapper.selectHospitalPersonCertificateByIds(Collections.singletonList(hospitalPersonInfo.getId()));
        //数据库中的
        List<String> hospitalPersonCertificateUrlList = Lists.newArrayList();
        //根据科室人员id删除科室人员资质证书信息表
        if (CollectionUtils.isNotEmpty(hospitalPersonCertificateList)) {
            hospitalPersonCertificateUrlList = hospitalPersonCertificateList.stream().filter(Objects::nonNull)
                    .filter(hospitalUrl -> (StringUtils.isNotBlank(hospitalUrl.getCertificateUrl())))
                    .map(HospitalPersonCertificate::getCertificateUrl).collect(Collectors.toList());
            Long[] longs = hospitalPersonCertificateList.stream().filter(Objects::nonNull).filter(item -> Objects.nonNull(item.getId())).collect(Collectors.toList()).stream().map(HospitalPersonCertificate::getId).toArray(Long[]::new);
            int deleteCount = hospitalPersonCertificateMapper.deleteHospitalPersonCertificateByIds(longs);
            if (deleteCount <= 0) {
                throw new ServiceException("修改科室人员信息失败，请联系管理员！");
            }
        }
        //前端传的
        List<String> hospitalPersonInfoCertificateUrlList = hospitalPersonInfo.getHospitalPersonCertificateList().stream().filter(Objects::nonNull)
                .filter(hospitalUrl -> (StringUtils.isNotBlank(hospitalUrl.getCertificateUrl())))
                .map(HospitalPersonCertificate::getCertificateUrl).collect(Collectors.toList());
        //数据库中的地址与前端传的地址做差集
        List<String> hospitalPersonCertificateUrlSubtract = new ArrayList<>(CollectionUtils.subtract(hospitalPersonCertificateUrlList, hospitalPersonInfoCertificateUrlList));
        //新增科室人员资质证书表
        for (HospitalPersonCertificate hospitalPersonCertificate : hospitalPersonInfo.getHospitalPersonCertificateList()) {
            hospitalPersonCertificate.setHospitalPersonId(hospitalPersonInfo.getId());
            hospitalPersonCertificate.setUpdateTime(LocalDateTime.now());
            hospitalPersonCertificate.setUpdateBy(SecurityUtils.getUsername());
            hospitalPersonCertificate.setCertificateCode(Constants.CERTIFICATE_CODE + generateSystemCodeUtil.generateSystemCode(Constants.CERTIFICATE_CODE));
        }
        if (CollectionUtils.isNotEmpty(hospitalPersonInfo.getHospitalPersonCertificateList())) {
            int hospitalPersonCertificates = hospitalPersonCertificateMapper.insertHospitalPersonCertificateList(hospitalPersonInfo.getHospitalPersonCertificateList());
            if (hospitalPersonCertificates <= 0) {
                throw new ServiceException("修改科室人员资质证书信息失败，请联系管理员！");
            }
        }
        //删除人员的头像
        if (StringUtils.isNotBlank(personInfo.getPersonPictureUrl()) && StringUtils.isNotBlank(hospitalPersonInfo.getPersonPictureUrl()) && !personInfo.getPersonPictureUrl().equals(hospitalPersonInfo.getPersonPictureUrl())) {
            this.deletePictureUrl(personInfo.getPersonPictureUrl());
        }
        //删除科室人员的资质证书
        if (CollectionUtils.isNotEmpty(hospitalPersonCertificateUrlSubtract)) {
            hospitalPersonCertificateUrlSubtract.forEach(this::deletePictureUrl);
        }
        return AjaxResult.success();
    }

    /**
     * 批量删除健康咨询-科室人员信息
     *
     * @param ids 需要删除的健康咨询-科室人员信息主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult deleteHospitalPersonInfoByIds(Long[] ids) {
        //根据科室人员id去查询对应的个人信息 使用流来获取所有的富文本
        List<HospitalPersonInfo> hospitalPersonInfos = hospitalPersonInfoMapper.selectHospitalPersonByIds(Arrays.asList(ids));
        if (CollectionUtils.isEmpty(hospitalPersonInfos)) {
            return AjaxResult.success();
        }
        //根据科室人员id删除人员信息表
        hospitalPersonInfoMapper.deleteHospitalPersonInfoByIds(ids);
        //根据科室人员id去查询对应的资质证书 使用流来获取所有的证书路径
        List<HospitalPersonCertificate> hospitalPersonCertificateList = hospitalPersonCertificateMapper.selectHospitalPersonCertificateByIds(Arrays.asList(ids));
        //删除人员资质证书表信息
        if (CollectionUtils.isNotEmpty(hospitalPersonCertificateList)) {
            hospitalPersonCertificateMapper.deletePersonCertificateByPersonIds(ids);
        }
        //使用流获取人员的头像地址
        List<String> personPictureUrlList = hospitalPersonInfos.stream().filter(Objects::nonNull)
                .filter(hospital -> (Objects.nonNull(hospital.getPersonPictureUrl())))
                .map(HospitalPersonInfo::getPersonPictureUrl).collect(Collectors.toList());
        //删除人员的头像
        if (CollectionUtils.isNotEmpty(personPictureUrlList)) {
            personPictureUrlList.forEach(this::deletePictureUrl);
        }
        //删除科室人员的资质证书
        List<String> hospitalPersonCertificateUrlList = hospitalPersonCertificateList.stream().filter(Objects::nonNull)
                .filter(hospitalUrl -> (StringUtils.isNotBlank(hospitalUrl.getCertificateUrl())))
                .map(HospitalPersonCertificate::getCertificateUrl).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(hospitalPersonCertificateUrlList)) {
            hospitalPersonCertificateUrlList.forEach(this::deletePictureUrl);
        }
        // 删除用户表信息
        List<Long> userId = new ArrayList<>();
        for (HospitalPersonInfo hospitalPersonInfo : hospitalPersonInfos) {
            SysUser sysUser = new SysUser();
            sysUser.setHospitalPersonId(hospitalPersonInfo.getId());
            List<SysUser> userList = userMapper.selectUserList(sysUser);
            List<Long> userIdList = userList.stream().map(SysUser::getUserId).collect(Collectors.toList());
            userId.addAll(userIdList);
        }
        userMapper.deleteUserByIds(userId.toArray(new Long[0]));
        return AjaxResult.success();
    }

    /**
     * 删除健康咨询-科室人员信息信息
     *
     * @param id 健康咨询-科室人员信息主键
     * @return 结果
     */
    @Override
    public int deleteHospitalPersonInfoById(Long id) {
        return hospitalPersonInfoMapper.deleteHospitalPersonInfoById(id);
    }


    /**
     * 修改数据校验电话与身份证号
     *
     * @param hospitalPersonInfo 前端传过来的
     * @param personInfo         数据库中查的
     * @return com.xinelu.common.core.domain.AjaxResult
     **/
    public AjaxResult verificationHospital(HospitalPersonInfoDTO hospitalPersonInfo, HospitalPersonInfo personInfo) {
        //校验联系电话是否正确
        if (Objects.nonNull(hospitalPersonInfo) && StringUtils.isNotBlank(hospitalPersonInfo.getPersonPhone())) {
            boolean phone = regexUtil.regexPhone(hospitalPersonInfo.getPersonPhone());
            if (BooleanUtils.isFalse(phone)) {
                return AjaxResult.error("您输入的联系电话" + hospitalPersonInfo.getPersonPhone() + "不正确，请重新输入！");
            }
        }
        //校验身份证号是否正确
        if (Objects.nonNull(hospitalPersonInfo) && StringUtils.isNotBlank(hospitalPersonInfo.getCardNo())) {
            boolean phone = regexUtil.regexCardNo(hospitalPersonInfo.getCardNo());
            if (BooleanUtils.isFalse(phone)) {
                return AjaxResult.error("您输入的身份证号" + hospitalPersonInfo.getCardNo() + "不正确，请重新输入！");
            }
        }
        //校验身份证号是否重复
        if (Objects.nonNull(hospitalPersonInfo) && StringUtils.isNotBlank(hospitalPersonInfo.getCardNo()) &&
                StringUtils.isNotBlank(personInfo.getCardNo()) &&
                !personInfo.getCardNo().equals(hospitalPersonInfo.getCardNo())) {
            int cardNoByCount = hospitalPersonInfoMapper.selectHospitalPersonInfoByCount(hospitalPersonInfo.getCardNo());
            if (cardNoByCount > 0) {
                return AjaxResult.error("您输入的身份证号" + hospitalPersonInfo.getCardNo() + "重复，请重新添加！");
            }
        }
        return null;
    }

    /**
     * 删除图片地址
     *
     * @param pictureUrl 图片地址
     **/
    @Override
    public void deletePictureUrl(String pictureUrl) {
        if (StringUtils.isBlank(pictureUrl)) {
            return;
        }
        String picture = XinELuConfig.getProfile() + pictureUrl.replaceAll("/profile", "");
        File checkReportNameFile = new File(picture);
        if (checkReportNameFile.exists()) {
            boolean delete = checkReportNameFile.delete();
            if (BooleanUtils.isFalse(delete)) {
                throw new ServiceException("图片地址删除失败！");
            }
        }
    }

    /**
     * 修改医生手机号和密码
     *
     * @param hospitalPersonInfo
     * @return
     */
    @Override
    public int editHospitalPersonInfo(HospitalPersonInfoDtoo hospitalPersonInfo) {
        return hospitalPersonInfoMapper.editHospitalPersonInfo(hospitalPersonInfo);
    }

    /**
     * @return com.xinelu.manage.domain.hospitalpersoninfo.HospitalPersonInfo
     * @Author mengkuiliang
     * @Description 根据科室人员编码查询人员信息
     * @Date 2023-10-20 020 14:37
     * @Param [personCode]
     **/
    @Override
    public HospitalPersonInfo getByPersonCode(String personCode, String status) {
        return hospitalPersonInfoMapper.getByPersonCode(personCode, status);
    }

    /**
     * @return void
     * @Author mengkuiliang
     * @Description 新增
     * @Date 2023-10-20 020 14:54
     * @Param [body]
     **/
    @Override
    public int insert(HospitalPersonInfo body) {
        return hospitalPersonInfoMapper.insertHospitalPersonInfo(body);
    }

    /**
     * @return int
     * @Author mengkuiliang
     * @Description 根据科室人员编号更新
     * @Date 2023-10-20 020 15:02
     * @Param [hospitalPersonInfo]
     **/
    @Override
    public int updateByPersonCode(HospitalPersonInfo hospitalPersonInfo) {
        return hospitalPersonInfoMapper.updateByPersonCode(hospitalPersonInfo);
    }

}
