package com.mortals.xhx.module.notice.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.mortals.framework.model.PageInfo;
import com.mortals.xhx.base.system.user.model.UserEntity;
import com.mortals.xhx.base.system.user.model.UserQuery;
import com.mortals.xhx.base.system.user.service.UserService;
import com.mortals.xhx.common.code.*;
import com.mortals.xhx.module.notice.model.NoticeStudyEntity;
import com.mortals.xhx.module.notice.model.NoticeStudyQuery;
import com.mortals.xhx.module.notice.service.NoticeStudyService;
import com.mortals.xhx.module.project.model.ProjectEntity;
import com.mortals.xhx.module.project.model.ProjectStudyEntity;
import com.mortals.xhx.module.project.model.ProjectStudyQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.xhx.module.notice.dao.NoticeDao;
import com.mortals.xhx.module.notice.model.NoticeEntity;
import com.mortals.xhx.module.notice.service.NoticeService;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * NoticeService
 * 学习公告 service实现
 *
 * @author zxfei
 * @date 2023-02-23
 */
@Service("noticeService")
public class NoticeServiceImpl extends AbstractCRUDServiceImpl<NoticeDao, NoticeEntity, Long> implements NoticeService {

    @Autowired
    private NoticeStudyService noticeStudyService;
    @Autowired
    private UserService userService;

    @Override
    protected void findAfter(NoticeEntity params, PageInfo pageInfo, Context context, List<NoticeEntity> list) throws AppException {
        list.stream().forEach(item -> {
            Map<Boolean, Long> collect = noticeStudyService.find(new NoticeStudyQuery().noticeId(item.getId())).stream().collect(Collectors.partitioningBy(x -> x.getNoticeStatus() == NoticeStatusEnum.已读.getValue(), Collectors.counting()));
            item.setStudyPersonRadio(collect.getOrDefault(true, 0L) + "/" + (collect.getOrDefault(false, 0L) + collect.getOrDefault(true, 0L)));
        });

        super.findAfter(params, pageInfo, context, list);
    }


    @Override
    protected void saveAfter(NoticeEntity entity, Context context) throws AppException {
        super.saveAfter(entity, context);
        if (!ObjectUtils.isEmpty(entity.getViewPersion()) && YesNoEnum.NO.getValue() == entity.getViewPersion()) {
            //全部工作人员
            List<UserEntity> workPersons = userService.find(new UserQuery().userType(UserType.WORK_PERSON.getValue()));
            List<NoticeStudyEntity> studyPersons = workPersons.stream().map(work -> {
                NoticeStudyEntity noticeStudyEntity = buildStudyPerson(entity, context, work);
                return noticeStudyEntity;
            }).collect(Collectors.toList());
            if (!ObjectUtils.isEmpty(studyPersons)) {
                noticeStudyService.save(studyPersons);
            }
        }

        //判断是否选择部门
        if (!ObjectUtils.isEmpty(entity.getDeptIds())) {
            //根据部门查询人员
            UserQuery userQuery = new UserQuery();
            userQuery.setUserType(UserType.WORK_PERSON.getValue());
            userQuery.setDeptIdList(entity.getDeptIds());
            List<UserEntity> workPersons = userService.find(userQuery);
            List<NoticeStudyEntity> studyPersons = workPersons.stream().map(work -> {
                NoticeStudyEntity noticeStudyEntity = buildStudyPerson(entity, context, work);
                return noticeStudyEntity;
            }).collect(Collectors.toList());
            if (!ObjectUtils.isEmpty(studyPersons)) {
                noticeStudyService.save(studyPersons);
            }
        }

        if (ObjectUtils.isEmpty(entity.getDeptIds()) && !ObjectUtils.isEmpty(entity.getPersonIds())) {
            UserQuery userQuery = new UserQuery();
            userQuery.setIdList(entity.getPersonIds());
            List<UserEntity> workPersons = userService.find(userQuery);
            List<NoticeStudyEntity> studyPersons = workPersons.stream().map(work -> {
                NoticeStudyEntity noticeStudyEntity = buildStudyPerson(entity, context, work);
                return noticeStudyEntity;
            }).collect(Collectors.toList());
            if (!ObjectUtils.isEmpty(studyPersons)) {
                noticeStudyService.save(studyPersons);
            }
        }

    }


    private NoticeStudyEntity buildStudyPerson(NoticeEntity entity, Context context, UserEntity work) {
        NoticeStudyEntity noticeStudyEntity = new NoticeStudyEntity();
        noticeStudyEntity.initAttrValue();
        noticeStudyEntity.setNoticeId(entity.getId());
        noticeStudyEntity.setNoticetType(entity.getNoticeType());
        noticeStudyEntity.setTitle(entity.getTitle());
        noticeStudyEntity.setUserId(work.getId());
        noticeStudyEntity.setUserName(work.getRealName());
        noticeStudyEntity.setDeptName(work.getDeptName());
        noticeStudyEntity.setNoticeStatus(NoticeStatusEnum.未读.getValue());
        noticeStudyEntity.setTop(TopEnum.否.getValue());
        // noticeStudyEntity.setViewTime(new Date());
        noticeStudyEntity.setRemark("");
        noticeStudyEntity.setCreateTime(new Date());
        noticeStudyEntity.setCreateUserId(this.getContextUserId(context));
        return noticeStudyEntity;
    }


    @Override
    protected void updateAfter(NoticeEntity entity, Context context) throws AppException {
        super.updateAfter(entity, context);
        //编辑 差集计算
        //查询已有人员公告
        List<NoticeStudyEntity> oldNoticeStudy = noticeStudyService.find(new NoticeStudyQuery().noticeId(entity.getId()));
        List<NoticeStudyEntity> noticeStudyEntities = new ArrayList<>();
        //计算需要新增或者删除的人员公告列表
        if (!ObjectUtils.isEmpty(entity.getViewPersion()) && YesNoEnum.NO.getValue() == entity.getViewPersion()) {
            //全部工作人员
            List<UserEntity> workPersons = userService.find(new UserQuery().userType(UserType.WORK_PERSON.getValue()));
            noticeStudyEntities = workPersons.stream().map(work -> {
                NoticeStudyEntity noticeStudyEntity = buildStudyPerson(entity, context, work);
                return noticeStudyEntity;
            }).collect(Collectors.toList());

        }

        //判断是否选择部门
        if (!ObjectUtils.isEmpty(entity.getDeptIds())) {
            //根据部门查询人员
            UserQuery userQuery = new UserQuery();
            userQuery.setUserType(UserType.WORK_PERSON.getValue());
            userQuery.setDeptIdList(entity.getDeptIds());
            List<UserEntity> workPersons = userService.find(userQuery);
            noticeStudyEntities = workPersons.stream().map(work -> {
                NoticeStudyEntity noticeStudyEntity = buildStudyPerson(entity, context, work);
                return noticeStudyEntity;
            }).collect(Collectors.toList());
        }

        if (ObjectUtils.isEmpty(entity.getDeptIds()) && !ObjectUtils.isEmpty(entity.getPersonIds())) {
            UserQuery userQuery = new UserQuery();
            userQuery.setIdList(entity.getPersonIds());
            List<UserEntity> workPersons = userService.find(userQuery);
            noticeStudyEntities = workPersons.stream().map(work -> {
                NoticeStudyEntity noticeStudyEntity = buildStudyPerson(entity, context, work);
                return noticeStudyEntity;
            }).collect(Collectors.toList());
        }

        //差集计算 noticeStudyEntities 与   oldNoticeStudy
        //获取新增的元素
        List<NoticeStudyEntity> addList = CollUtil.subtract(noticeStudyEntities, oldNoticeStudy).stream().collect(Collectors.toList());

        if (ObjectUtils.isEmpty(addList)) {
            noticeStudyService.save(addList);
        }
        //需删除的元素
        List<NoticeStudyEntity> delList = CollUtil.subtract(oldNoticeStudy, noticeStudyEntities).stream().collect(Collectors.toList());
        if (!ObjectUtils.isEmpty(delList)) {
            Long[] delIds = delList.stream().map(item -> {
                return noticeStudyService.selectOne(new NoticeStudyQuery().noticeId(item.getNoticeId()).userId(item.getUserId()));
            }).filter(f -> f != null).map(item -> item.getId()).toArray(Long[]::new);
            if (!ObjectUtils.isEmpty(delIds)) {
                noticeStudyService.remove(delIds, context);
            }
        }
    }


    @Override
    protected void removeAfter(Long[] ids, Context context, int result) throws AppException {
        super.removeAfter(ids, context, result);
        List<Long> idList = Arrays.asList(ids);
        Long[] delIds = noticeStudyService.find(new NoticeStudyQuery().noticeIdList(idList)).stream().map(item -> item.getId()).toArray(Long[]::new);
        if (!ObjectUtils.isEmpty(delIds)) {
            noticeStudyService.remove(delIds, context);
        }
    }
}