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


import com.xinelu.common.config.XinELuConfig;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.AgeUtil;
import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.common.utils.StringUtils;
import com.xinelu.common.utils.regex.RegexUtil;
import com.xinelu.common.utils.sign.Md5Utils;
import com.xinelu.manage.domain.patientinfo.PatientInfo;
import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper;
import com.xinelu.manage.mapper.sysarea.SysAreaMapper;
import com.xinelu.manage.service.patientinfo.IPatientInfoService;
import com.xinelu.manage.vo.patientinfo.PatientInfoVO;
import com.xinelu.manage.vo.sysarea.SysAreaVO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.File;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 被护理人基本信息Service业务层处理
 *
 * @author xinelu
 * @date 2022-09-02
 */
@Service
public class PatientInfoServiceImpl implements IPatientInfoService {
    @Resource
    private PatientInfoMapper patientInfoMapper;
    @Resource
    private RegexUtil regexUtil;
    @Resource
    private SysAreaMapper sysAreaMapper;

    /**
     * 查询被护理人基本信息
     *
     * @param id 被护理人基本信息主键
     * @return 被护理人基本信息
     */
    @Override
    public PatientInfoVO selectPatientInfoById(Long id) {
        //根据Id获取会员信息
        PatientInfoVO patientInfoById = patientInfoMapper.getPatientInfoById(id);
        if (Objects.isNull(patientInfoById)) {
            throw new ServiceException("当前用户信息不存在，无法进行修改！");
        }
        //判断当前用户信息是否已经完善，只有完善的才可以修改用户信息
        if (Objects.isNull(patientInfoById.getLoginFlag())) {
            throw new ServiceException("当前用户信息未完善，无法进行修改！");
        }
        if (Objects.nonNull(patientInfoById.getBirthDate())) {
            patientInfoById.setAge(AgeUtil.getAgeMonth(String.valueOf(patientInfoById.getBirthDate())));
        }
        //根据区域编号查询上级区域信息
        SysAreaVO superiorRegions = sysAreaMapper.getSubordinateRegionsFindSuperiorRegions(StringUtils.isBlank(patientInfoById.getAreaCode()) ? "" : patientInfoById.getAreaCode());
        ArrayList<SysAreaVO> sysArea = new ArrayList<>();
        sysArea.add(superiorRegions);
        patientInfoById.setSysAreaVOList(sysArea);
        return patientInfoById;
    }

	@Override public PatientInfoVO selectPatientInfoByCardNo(String cardNo) {
		return patientInfoMapper.getPatientInfoByCardNo(cardNo);
	}

	/**
     * 查询被护理人基本信息列表
     *
     * @param patientInfo 被护理人基本信息
     * @return 被护理人基本信息
     */
    @Override
    public List<PatientInfoVO> selectPatientInfoList(PatientInfoVO patientInfo) {
        List<PatientInfoVO> patientInfoVO = patientInfoMapper.selectPatientInfoList(patientInfo);
        List<String> areaCodeList = patientInfoVO
                .stream().filter(Objects::nonNull)
                .map(PatientInfoVO::getAreaCode)
                .filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(areaCodeList)) {
            return patientInfoVO;
        }
        // 获取本护理站的区域信息
        List<SysAreaVO> nurseStationAreaByList = sysAreaMapper.getNurseStationAreaByList(areaCodeList);
        if (CollectionUtils.isEmpty(nurseStationAreaByList)) {
            return patientInfoVO;
        }
        //以护理站id进行分组将标签配置信息转为Map集合
        Map<String, List<SysAreaVO>> nurseStationAreaMap = nurseStationAreaByList.stream()
                .filter(Objects::nonNull)
                .filter(item -> Objects.nonNull(item.getStreetCode()))
                .collect(Collectors.groupingBy(SysAreaVO::getStreetCode));
        patientInfoVO.forEach(item ->
                item.setSysAreaVOList(nurseStationAreaMap.getOrDefault(Objects.isNull(item.getAreaCode()) ? 0L : item.getAreaCode(), Lists.newArrayList())));
        return patientInfoVO;
    }

    /**
     * 新增被护理人基本信息
     *
     * @param patientInfo 被护理人基本信息
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertPatientInfo(PatientInfo patientInfo) {
        patientInfo.setCreateBy(SecurityUtils.getUsername());
        patientInfo.setCreateTime(LocalDateTime.now());
        return patientInfoMapper.insertPatientInfo(patientInfo);
    }

    /**
     * 修改被护理人基本信息
     *
     * @param patientInfo 被护理人基本信息
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updatePatientInfo(PatientInfo patientInfo) {
        boolean regexPhone = regexUtil.regexPhone(patientInfo.getPhone());
        if (BooleanUtils.isFalse(regexPhone)) {
            return AjaxResult.error("手机号格式不正确!");
        }
        boolean regexCardNo = regexUtil.regexCardNo(patientInfo.getCardNo());
        if (BooleanUtils.isFalse(regexCardNo)) {
            return AjaxResult.error("身份证号格式不正确!");
        }
        //调用md5加密方法
        String changePassword = Md5Utils.hash(patientInfo.getPassword());
        patientInfo.setPassword(changePassword);
        patientInfo.setUpdateTime(LocalDateTime.now());
        patientInfo.setUpdateBy(SecurityUtils.getUsername());
        int updatePatientInfo = patientInfoMapper.updatePatientInfo(patientInfo);
        if (updatePatientInfo <= 0) {
            throw new ServiceException("修改被护理人信息失败，请联系管理员！");
        }
        return AjaxResult.success();
    }

    /**
     * 批量删除被护理人基本信息
     *
     * @param ids 需要删除的被护理人基本信息主键
     * @return 结果
     */
    @Override
    public int deletePatientInfoByIds(Long[] ids) {
        return patientInfoMapper.deletePatientInfoByIds(ids);
    }

    /**
     * 修改被护理人头像图片用于AppletLoginServiceImpl
     *
     * @param openid         用户编号
     * @param headPictureUrl 个人头像地址
     * @return boolean 结果
     **/
    @Override
    public boolean updateHeadPatientHead(String openid, String headPictureUrl) {
        return patientInfoMapper.updateHeadPatientHead(openid, headPictureUrl) > 0;
    }

    /**
     * 删除旧图片
     *
     * @param pictureUrlList 路径
     * @return 结果
     */
    @Override
    public AjaxResult updatePicture(List<String> pictureUrlList) {
        if (CollectionUtils.isEmpty(pictureUrlList)) {
            return AjaxResult.success();
        }
        for (String pictureUrl : pictureUrlList) {
            if (StringUtils.isBlank(pictureUrl)) {
                continue;
            }
            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("图片文件删除失败！");
                }
            }
        }
        return AjaxResult.success();
    }

    /**
     * PC端重置密码
     *
     * @param id       会员id
     * @param password 密码
     * @return AjaxResult
     */
    @Override
    public AjaxResult updatePasswordById(Long id, String password) {
        PatientInfo patientInfo = new PatientInfo();
        patientInfo.setId(id);
        patientInfo.setPassword(Md5Utils.hash(password));
        int update = patientInfoMapper.updatePatientInfo(patientInfo);
        if (update <= 0) {
            throw new ServiceException("重置密码失败，请联系管理员！");
        }
        return AjaxResult.success();
    }
}