package com.zhgd.xmgl.modules.basicdata.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhgd.jeecg.common.util.PageUtil;
import com.zhgd.xmgl.modules.basicdata.dto.NoticeDto;
import com.zhgd.xmgl.modules.basicdata.entity.AnnexFile;
import com.zhgd.xmgl.modules.basicdata.entity.Government;
import com.zhgd.xmgl.modules.basicdata.entity.Notice;
import com.zhgd.xmgl.modules.basicdata.entity.NoticeAccept;
import com.zhgd.xmgl.modules.basicdata.mapper.NoticeMapper;
import com.zhgd.xmgl.modules.basicdata.service.IAnnexFileService;
import com.zhgd.xmgl.modules.basicdata.service.IGovernmentService;
import com.zhgd.xmgl.modules.basicdata.service.INoticeAcceptService;
import com.zhgd.xmgl.modules.basicdata.service.INoticeService;
import com.zhgd.xmgl.modules.basicdata.vo.NoticeVo;
import com.zhgd.xmgl.security.SecurityUser;
import com.zhgd.xmgl.security.SecurityUtil;
import com.zhgd.xmgl.util.ParamEnum;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: 通知公告表
 * @author： pengj
 * @date：   2023-03-02
 * @version： V1.0
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class NoticeServiceImpl extends ServiceImpl<NoticeMapper, Notice> implements INoticeService {

    @Autowired
    private IAnnexFileService annexFileService;

    @Autowired
    private INoticeAcceptService noticeAcceptService;

    @Autowired
    private IGovernmentService governmentService;

    @Override
    public Page<Notice> toMePageList(Map<String, Object> map) {
        QueryWrapper<Notice> wrapper = Wrappers.<Notice>query();
        String title = MapUtils.getString(map, "title");
        String content = MapUtils.getString(map, "content");
        Page<Notice> page = PageUtil.getPage(map);
        SecurityUser user = SecurityUtil.getUser();
        if (StringUtils.isNotBlank(user.getEngineeringSn())) {
            wrapper.eq("a.accept", user.getEngineeringSn());
        } else {
            wrapper.eq("a.accept", user.getSn());
        }
        if (StringUtils.isNotBlank(title)) {
            wrapper.like("n.title", title);
        }
        if (StringUtils.isNotBlank(content)) {
            wrapper.like("n.content", content);
        }
        return baseMapper.toMePageList(page, wrapper);
    }

    @Override
    public NoticeDto getDetail(Notice notice) {
        NoticeDto noticeDto = new NoticeDto();
        BeanUtils.copyProperties(notice, noticeDto);
        Government government = governmentService.getOne(Wrappers.<Government>lambdaQuery().eq(Government::getGovernmentSn, notice.getCreateBy()));
        noticeDto.setCreateByName(government.getGovernmentName());
        List<AnnexFile> annexFileList = annexFileService.list(Wrappers.<AnnexFile>lambdaQuery().eq(AnnexFile::getRelevanceId, notice.getNoticeId())
                .eq(AnnexFile::getFileType, ParamEnum.AnnexFileType.NOTICE.getValue()));
        List<NoticeAccept> noticeAcceptList = noticeAcceptService.getList(notice.getNoticeId());
        noticeDto.setAcceptList(noticeAcceptList);
        noticeDto.setAcceptSnList(noticeAcceptList.stream().map(n -> n.getAccept()).collect(Collectors.toList()));
        noticeDto.setAnnexFileList(annexFileList);
        return noticeDto;
    }

    @Override
    public boolean saveInfo(NoticeVo noticeVo) {
        Notice notice = new Notice();
        BeanUtils.copyProperties(noticeVo, notice);
        notice.setCreateBy(SecurityUtil.getUser().getSn());
        notice.setCreateTime(new Date());
        this.save(notice);
        return saveDetail(noticeVo, notice.getNoticeId());
    }

    @Override
    public boolean updateInfo(NoticeVo noticeVo) {
        Notice notice = new Notice();
        BeanUtils.copyProperties(noticeVo, notice);
        this.updateById(notice);
        delDetail(notice.getNoticeId());
        return saveDetail(noticeVo, notice.getNoticeId());
    }

    @Override
    public boolean delInfo(Notice notice) {
        delDetail(notice.getNoticeId());
        return this.removeById(notice.getNoticeId());
    }

    @Override
    public boolean read(Notice notice) {
        SecurityUser user = SecurityUtil.getUser();
        if (!user.isManager() &&  StringUtils.isBlank(user.getEngineeringSn())) {
            return false;
        }
        String accept = user.getSn();
        if (StringUtils.isNotBlank(user.getEngineeringSn())) {
            accept = user.getEngineeringSn();
        }
        LambdaUpdateWrapper<NoticeAccept> wrapper = Wrappers.<NoticeAccept>lambdaUpdate();
        wrapper.set(NoticeAccept::getIsRead, 1);
        wrapper.eq(NoticeAccept::getNoticeId, notice.getNoticeId());
        wrapper.eq(NoticeAccept::getAccept, accept);
        return noticeAcceptService.update(wrapper);
    }

    private boolean saveDetail(NoticeVo noticeVo, Long noticeId) {
        List<AnnexFile> annexFileList = noticeVo.getAnnexFileList();
        annexFileList.stream().forEach(a -> {
            a.setRelevanceId(noticeId.toString());
            a.setCreateTime(new Date());
            a.setFileType(ParamEnum.AnnexFileType.NOTICE.getValue());
        });
        annexFileService.saveBatch(annexFileList);
        List<NoticeAccept> acceptList = new ArrayList<>();
        noticeVo.getAccepts().stream().forEach(a -> {
            NoticeAccept noticeAccept = new NoticeAccept();
            noticeAccept.setNoticeId(noticeId);
            noticeAccept.setAccept(a);
            acceptList.add(noticeAccept);
        });
        return noticeAcceptService.saveBatch(acceptList);
    }

    private boolean delDetail(Long noticeId) {
        annexFileService.remove(Wrappers.<AnnexFile>lambdaQuery().eq(AnnexFile::getRelevanceId, noticeId)
                .eq(AnnexFile::getFileType, ParamEnum.AnnexFileType.NOTICE.getValue()));
        return noticeAcceptService.remove(Wrappers.<NoticeAccept>lambdaQuery().eq(NoticeAccept::getNoticeId, noticeId));
    }
}
