package com.xinelu.applet.service.nurseappletpersoncenter.impl;

import com.xinelu.applet.mapper.nursepersonapplogin.NursePersonAppLoginMapper;
import com.xinelu.applet.service.nurseappletpersoncenter.NurseAppletPersonCenterService;
import com.xinelu.applet.vo.nursepersonapplogin.NurseStationPersonUserVO;
import com.xinelu.common.config.XinELuConfig;
import com.xinelu.common.constant.Constants;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.core.page.TableDataInfo;
import com.xinelu.common.enums.ModifyCheckStatusEnum;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.AgeUtil;
import com.xinelu.common.utils.PageServiceUtil;
import com.xinelu.common.utils.codes.GenerateSystemCodeUtil;
import com.xinelu.common.utils.file.FileUploadUtils;
import com.xinelu.common.utils.file.FileUtils;
import com.xinelu.common.utils.file.MimeTypeUtils;
import com.xinelu.manage.domain.nursestationperson.NurseStationPerson;
import com.xinelu.manage.domain.nursestationpersoncheck.NurseStationPersonCheck;
import com.xinelu.manage.dto.nursestationperson.NurseStationPersonCheckDTO;
import com.xinelu.manage.mapper.nursestation.NurseStationMapper;
import com.xinelu.manage.mapper.nursestationperson.NurseStationPersonMapper;
import com.xinelu.manage.mapper.nursestationpersoncheck.NurseStationPersonCheckMapper;
import com.xinelu.manage.mapper.nursestationpersonrevenue.NurseStationPersonRevenueMapper;
import com.xinelu.manage.vo.nursestation.NurseStationSysUserVO;
import com.xinelu.manage.vo.nursestationpersonrevenue.NurseStationPersonRevenueVO;
import com.xinelu.manage.vo.nursestationpersonrevenue.PersonRevenueCountVO;
import com.xinelu.manage.vo.nursestationpersonrevenue.RevenueTimeDTO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 护理人员登录个人中心
 *
 * @author ljh
 * @version 1.0
 * Create by 2023/3/30 17:05
 */
@Service
public class NurseAppletPersonCenterServiceImpl implements NurseAppletPersonCenterService {

    @Resource
    private NursePersonAppLoginMapper nursePersonAppLoginMapper;
    @Resource
    private NurseStationMapper nurseStationMapper;
    @Resource
    private NurseStationPersonRevenueMapper nurseStationPersonRevenueMapper;
    @Resource
    private XinELuConfig xinELuConfig;
    @Resource
    private NurseStationPersonMapper nurseStationPersonMapper;
    @Resource
    private NurseStationPersonCheckMapper nurseStationPersonCheckMapper;
    @Resource
    private GenerateSystemCodeUtil generateSystemCodeUtil;
    @Resource
    private PageServiceUtil pageServiceUtil;

    /**
     * 护理人员登录个人中心
     *
     * @param nursePersonId 护理员id
     * @return 结果
     */
    @Override
    public NurseStationPersonUserVO nurseAppletPersonCenter(Long nursePersonId) {
        NurseStationPersonUserVO nurseStationPersonById = nursePersonAppLoginMapper.getNurseStationPersonById(nursePersonId);
        //算出年龄以及平均星级评价
        if (Objects.nonNull(nurseStationPersonById) && Objects.nonNull(nurseStationPersonById.getBirthDate())) {
            nurseStationPersonById.setAge(AgeUtil.getAgeMonth(String.valueOf(nurseStationPersonById.getBirthDate())));
        }
        int avgEvaluateSatisfaction = nurseStationPersonMapper.selectAvgEvaluateSatisfaction(nursePersonId);
        nurseStationPersonById.setEvaluateStarCount(Math.round(avgEvaluateSatisfaction));
        //查询所属的护理站信息
        if (StringUtils.isBlank(nurseStationPersonById.getNurseStationIds())) {
            return nurseStationPersonById;
        }
        List<String> nurseTypeCodeList = Arrays.asList(StringUtils.split(nurseStationPersonById.getNurseStationIds(), ","));
        List<Long> stationIdList = nurseTypeCodeList.stream().map(s -> Long.parseLong(s.trim())).distinct().collect(Collectors.toList());
        List<NurseStationSysUserVO> stationIds = nurseStationMapper.getNurseStationIds(stationIdList);
        nurseStationPersonById.setNurseStationSysUserVOList(stationIds);
        //根据护理员id更新星级评级
        NurseStationPerson nurseStationPerson = new NurseStationPerson();
        nurseStationPerson.setId(nursePersonId);
        nurseStationPerson.setEvaluateStarCount(avgEvaluateSatisfaction);
        nurseStationPersonMapper.updateNurseStationPerson(nurseStationPerson);
        return nurseStationPersonById;
    }

    /**
     * 个人中心-我的收益功能
     *
     * @param revenueTime 护理员信息
     * @return NurseStationPersonRevenueVO
     */
    @Override
    public PersonRevenueCountVO selectPersonRevenue(RevenueTimeDTO revenueTime) {
        revenueTime.setStartTime(LocalDate.now().atTime(0, 0, 0));
        revenueTime.setEndTime(LocalDateTime.now());
        if (Objects.nonNull(revenueTime.getMonthTime())) {
            revenueTime.setMonthStartDateTime(revenueTime.getMonthTime().with(TemporalAdjusters.firstDayOfMonth()).atTime(0, 0, 0));
            revenueTime.setMonthEndDateTime(revenueTime.getMonthTime().with(TemporalAdjusters.lastDayOfMonth()).atTime(23, 59, 59));
            return nurseStationPersonRevenueMapper.selectRevenueAmountById(revenueTime);
        }
        if (Objects.nonNull(revenueTime.getMonthStartTime()) && Objects.nonNull(revenueTime.getMonthEndTime())) {
            revenueTime.setMonthStartDateTime(revenueTime.getMonthStartTime().atTime(0, 0, 0));
            revenueTime.setMonthEndDateTime(revenueTime.getMonthEndTime().atTime(23, 59, 59));
            return nurseStationPersonRevenueMapper.selectRevenueAmountById(revenueTime);
        }
        revenueTime.setMonthStartDateTime(LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()).atTime(0, 0, 0));
        revenueTime.setMonthEndDateTime(LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()).atTime(23, 59, 59));
        return nurseStationPersonRevenueMapper.selectRevenueAmountById(revenueTime);
    }

    /**
     * 我的收益功能明细
     *
     * @param revenueTime 护理员信息
     * @return NurseStationPersonRevenueVO
     */
    @Override
    public TableDataInfo selectPersonRevenueDetails(RevenueTimeDTO revenueTime) {
        if (Objects.isNull(revenueTime) || Objects.isNull(revenueTime.getNurseStationPersonId())) {
            return pageServiceUtil.getDataTable(new ArrayList<>());
        }
        if (Objects.nonNull(revenueTime.getMonthTime())) {
            revenueTime.setMonthStartDateTime(revenueTime.getMonthTime().with(TemporalAdjusters.firstDayOfMonth()).atTime(0, 0, 0));
            revenueTime.setMonthEndDateTime(revenueTime.getMonthTime().with(TemporalAdjusters.lastDayOfMonth()).atTime(23, 59, 59));
            pageServiceUtil.startPage();
            List<NurseStationPersonRevenueVO> list = nurseStationPersonRevenueMapper.selectRevenueDetails(revenueTime);
            return pageServiceUtil.getDataTable(list);
        }
        if (Objects.nonNull(revenueTime.getMonthStartTime()) && Objects.nonNull(revenueTime.getMonthEndTime())) {
            revenueTime.setMonthStartDateTime(revenueTime.getMonthStartTime().atTime(0, 0, 0));
            revenueTime.setMonthEndDateTime(revenueTime.getMonthEndTime().atTime(23, 59, 59));
            pageServiceUtil.startPage();
            List<NurseStationPersonRevenueVO> list = nurseStationPersonRevenueMapper.selectRevenueDetails(revenueTime);
            return pageServiceUtil.getDataTable(list);
        }
        revenueTime.setMonthStartDateTime(LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()).atTime(0, 0, 0));
        revenueTime.setMonthEndDateTime(LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()).atTime(23, 59, 59));
        pageServiceUtil.startPage();
        List<NurseStationPersonRevenueVO> list = nurseStationPersonRevenueMapper.selectRevenueDetails(revenueTime);
        return pageServiceUtil.getDataTable(list);
    }

    /**
     * 小程序app更新护理人员主表信息与证书信息
     *
     * @param nurseStationPersonCheckDTO 护理人员主表信息与证书信息
     * @return AjaxResult
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updateNursePersonCheck(NurseStationPersonCheckDTO nurseStationPersonCheckDTO) {
        //更新护理人员主表信息
        nurseStationPersonCheckDTO.setModifyInfoFlag(1);
        nurseStationPersonCheckDTO.setModifyCheckStatus(ModifyCheckStatusEnum.NOT_CHECK.getInfo());
        nurseStationPersonMapper.updateNursePersonCheck(nurseStationPersonCheckDTO);
        //更新sysUser表信息
        nursePersonAppLoginMapper.updateHeadAvatarHeadUserId(nurseStationPersonCheckDTO.getUserId(), nurseStationPersonCheckDTO.getAvatar());
        if (CollectionUtils.isEmpty(nurseStationPersonCheckDTO.getNurseStationPersonCheckList())) {
            return AjaxResult.success();
        }
        //根据护理人员id去查询护理人员信息修改审核信息表信息
        NurseStationPersonCheck nurseStationPersonCheck = new NurseStationPersonCheck();
        nurseStationPersonCheck.setNurseStationPersonId(nurseStationPersonCheckDTO.getId());
        List<NurseStationPersonCheck> nurseStationPersonChecks = nurseStationPersonCheckMapper.selectNurseStationPersonCheckList(nurseStationPersonCheck);
        if (CollectionUtils.isNotEmpty(nurseStationPersonChecks)) {
            //根据护理人员id筛选护理人员信息修改审核信息表的数据 有就删 确保信息是最新的
            Long[] longList = nurseStationPersonChecks.stream().filter(Objects::nonNull).filter(check -> (Objects.nonNull(check.getId()))).map(NurseStationPersonCheck::getId).toArray(Long[]::new);
            int deleteNurseStationPersonCheckByIds = nurseStationPersonCheckMapper.deleteNurseStationPersonCheckByIds(longList);
            if (deleteNurseStationPersonCheckByIds <= 0) {
                throw new ServiceException("修改护理人员个人信息失败，请联系管理员！");
            }
        }
        List<NurseStationPersonCheck> nurseStationPersonCheckList = nurseStationPersonCheckDTO.getNurseStationPersonCheckList();
        if (CollectionUtils.isNotEmpty(nurseStationPersonCheckList)) {
            nurseStationPersonCheckList.forEach(item -> {
                item.setNurseStationPersonId(nurseStationPersonCheckDTO.getId());
                item.setCreateTime(LocalDateTime.now());
                item.setCertificateCode(Constants.PERSON_CERTIFICATE_CODE + generateSystemCodeUtil.generateSystemCode(Constants.PERSON_CERTIFICATE_CODE));
                item.setCertificateName("资质证书" + Constants.PERSON_CERTIFICATE_CODE + generateSystemCodeUtil.generateSystemCode(Constants.PERSON_CERTIFICATE_CODE));
            });
            int stationPersonCheckList = nurseStationPersonCheckMapper.insertNurseStationPersonCheckList(nurseStationPersonCheckList);
            if (stationPersonCheckList <= 0) {
                throw new ServiceException("修改护理人员个人信息失败，请联系管理员！");
            }
        }
        //删除原有的审核图片文件
        if (CollectionUtils.isNotEmpty(nurseStationPersonChecks)) {
            List<String> pageCertificateUrlList = nurseStationPersonCheckDTO.getNurseStationPersonCheckList().stream().filter(item -> StringUtils.isNotBlank(item.getCertificateUrl())).map(NurseStationPersonCheck::getCertificateUrl).collect(Collectors.toList());
            List<String> certificateUrlList = nurseStationPersonChecks.stream().filter(Objects::nonNull).filter(check -> (StringUtils.isNotBlank(check.getCertificateUrl()))).map(NurseStationPersonCheck::getCertificateUrl).collect(Collectors.toList());
            List<String> subtractList = new ArrayList<>(CollectionUtils.subtract(certificateUrlList, pageCertificateUrlList));
            for (String certificateUrl : subtractList) {
                FileUtils.deleteSystemFile(certificateUrl);
            }
        }
        return AjaxResult.success();
    }

    /**
     * 修改护理站人员状态信息
     *
     * @param nurseStationPerson 护理站人员信息
     * @return 结果
     */
    @Override
    public AjaxResult updateNursePersonWorkStatus(NurseStationPerson nurseStationPerson) {
        //更新护理人员主表信息
        int personWorkStatusWorkStatus = nurseStationPersonMapper.updateNursePersonWorkStatus(nurseStationPerson);
        if (personWorkStatusWorkStatus <= 0) {
            throw new ServiceException("更新护理人员状态信息失败，请联系管理员！");
        }
        return AjaxResult.success();
    }


    /**
     * 护理员App和小程序护理员上传证书
     *
     * @param file          图片文件
     * @param nursePersonId 护理员id
     * @return 结果
     * @throws Exception 异常信息
     */
    @Override
    public AjaxResult uploadNurseStationPersonCertificateUrl(MultipartFile file, Long nursePersonId) throws Exception {
        if (StringUtils.isBlank(file.getOriginalFilename())) {
            return AjaxResult.error("请选择所要上传的证书图片！");
        }
        //获取路径名称
        String uploadPathUrl = XinELuConfig.getProfile() + xinELuConfig.getPersonCertificateCheckUrl();
        //上传图片
        String pictureName = FileUploadUtils.uploadNurseStationPath(uploadPathUrl, file, MimeTypeUtils.IMAGE_EXTENSION);
        if (StringUtils.isBlank(pictureName)) {
            throw new ServiceException(pictureName + "证书图片上传失败，请联系管理员！");
        }
        //获取返回值
        AjaxResult ajax = AjaxResult.success("上传成功！");
        ajax.put("imgUrl", pictureName);
        return ajax;
    }
}
