package com.hdkj.lt.bf.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hdkj.lt.base.exception.BusinessException;
import com.hdkj.lt.base.model.response.PageVO;
import com.hdkj.lt.bf.entity.FhzgNotice;
import com.hdkj.lt.bf.entity.FhzgNoticeAttachment;
import com.hdkj.lt.bf.entity.FhzgNoticeReceiveRecord;
import com.hdkj.lt.bf.entity.dto.*;
import com.hdkj.lt.bf.entity.vo.NoticeFileListVO;
import com.hdkj.lt.bf.entity.vo.NoticeListVO;
import com.hdkj.lt.bf.entity.vo.NoticeVO;
import com.hdkj.lt.bf.mapper.FhzgNoticeMapper;
import com.hdkj.lt.bf.service.FhzgNoticeAttachmentService;
import com.hdkj.lt.bf.service.FhzgNoticeReceiveRecordService;
import com.hdkj.lt.bf.service.FhzgNoticeService;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.model.LoginUser;
import lombok.RequiredArgsConstructor;
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.stream.Collectors;

/**
 * @author Sunlit
 * @description 针对表【fhzg_notice】的数据库操作Service实现
 * @createDate 2025-12-26 10:20:52
 */
@Service
@RequiredArgsConstructor
public class FhzgNoticeServiceImpl extends ServiceImpl<FhzgNoticeMapper, FhzgNotice>
        implements FhzgNoticeService {

    private final FhzgNoticeAttachmentService noticeAttachmentService;

    private final FhzgNoticeReceiveRecordService noticeReceiveRecordService;

    @Override
    public List<AttachmentDTO> getFileTabList() {
        List<FhzgNotice> list = this.list(new LambdaUpdateWrapper<FhzgNotice>().eq(FhzgNotice::getType, 0)
                .eq(FhzgNotice::getStatus, 1));
        List<AttachmentDTO> attachmentDTOList = new ArrayList<>();
        list.forEach(
                i -> {
                    AttachmentDTO attachmentDTO = new AttachmentDTO();
                    attachmentDTO.setId(i.getId());
                    attachmentDTO.setName(i.getTitle());
                    attachmentDTOList.add(attachmentDTO);
                }
        );
        return attachmentDTOList;
    }

    @Override
    public PageVO<NoticeFileListVO> getFileList(NoticeFileListDTO noticeFileListDTO) {
        LambdaQueryWrapper<FhzgNoticeAttachment> fhzgNoticeAttachmentLambdaQueryWrapper = new LambdaQueryWrapper<>();
        fhzgNoticeAttachmentLambdaQueryWrapper.eq(FhzgNoticeAttachment::getStatus, 1);
        Page<FhzgNoticeAttachment> fhzgNoticeAttachmentPage = new Page<>();
        fhzgNoticeAttachmentPage.setCurrent(noticeFileListDTO.getPageNum());
        fhzgNoticeAttachmentPage.setSize(noticeFileListDTO.getPageSize());
        Page<FhzgNoticeAttachment> page = noticeAttachmentService.page(fhzgNoticeAttachmentPage,
                fhzgNoticeAttachmentLambdaQueryWrapper
                        .eq(FhzgNoticeAttachment::getNoticeId, noticeFileListDTO.getId())
                        .orderByDesc(FhzgNoticeAttachment::getCreateTime));
        PageVO<NoticeFileListVO> pageVO = new PageVO<>();
        List<NoticeFileListVO> noticeFileListVOList = new ArrayList<>();
        page.getRecords().forEach(i -> {
            NoticeFileListVO noticeFileListVO = new NoticeFileListVO();
            noticeFileListVO.setAttachmentId(i.getAttachmentId());
            noticeFileListVO.setAttachmentName(i.getAttachmentName());
            noticeFileListVO.setCreateTime(i.getCreateTime());
            noticeFileListVO.setStatus(i.getStatus());
            noticeFileListVOList.add(noticeFileListVO);

        });
        pageVO.setRecords(noticeFileListVOList);
        pageVO.setTotal(page.getTotal());
        pageVO.setPageSize(page.getSize());
        pageVO.setPageNum(page.getCurrent());
        return pageVO;
    }

    @Override
    public PageVO<NoticeListVO> getList(NoticeListDTO noticeListDTO) {
        Page<FhzgNotice> fhzgNoticePage = new Page<>();
        fhzgNoticePage.setCurrent(noticeListDTO.getPageNum());
        fhzgNoticePage.setSize(noticeListDTO.getPageSize());
        LambdaQueryWrapper<FhzgNotice> fhzgNoticeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        fhzgNoticeLambdaQueryWrapper.like(noticeListDTO.getTitle() != null, FhzgNotice::getTitle, noticeListDTO.getTitle());
        fhzgNoticeLambdaQueryWrapper.eq(noticeListDTO.getType() != null, FhzgNotice::getType, noticeListDTO.getType());
        fhzgNoticeLambdaQueryWrapper.eq(noticeListDTO.getStatus() != null, FhzgNotice::getStatus, noticeListDTO.getStatus());
        fhzgNoticeLambdaQueryWrapper.between(noticeListDTO.getStartTime() != null && noticeListDTO.getEndTime() != null, FhzgNotice::getCreateTime, noticeListDTO.getStartTime(), noticeListDTO.getEndTime());
        fhzgNoticeLambdaQueryWrapper.like(noticeListDTO.getCreatorName() != null, FhzgNotice::getUserName, noticeListDTO.getCreatorName());
        fhzgNoticeLambdaQueryWrapper.orderByDesc(FhzgNotice::getCreateTime);
        Page<FhzgNotice> page = this.page(fhzgNoticePage, fhzgNoticeLambdaQueryWrapper);
        PageVO<NoticeListVO> pageVO = new PageVO<>();
        pageVO.setTotal(page.getTotal());
        pageVO.setPageSize(page.getSize());
        pageVO.setPageNum(page.getCurrent());
        List<NoticeListVO> noticeListVOList = new ArrayList<>();
        page.getRecords().forEach(i -> {
            NoticeListVO noticeListVO = new NoticeListVO();
            noticeListVO.setId(String.valueOf(i.getId()));
            noticeListVO.setTitle(i.getTitle());
            noticeListVO.setType(i.getType());
            noticeListVO.setStatus(i.getStatus());
            noticeListVO.setCreateTime(i.getCreateTime());
            noticeListVO.setUserName(i.getUserName());
            List<FhzgNoticeAttachment> list = noticeAttachmentService.list(new LambdaQueryWrapper<FhzgNoticeAttachment>().eq(FhzgNoticeAttachment::getNoticeId, i.getId()));
            List<AttachmentDTO> attachmentDTOList = new ArrayList<>();
            list.forEach(
                    j -> {
                        AttachmentDTO attachmentDTO = new AttachmentDTO();
                        attachmentDTO.setId(j.getAttachmentId());
                        attachmentDTO.setName(j.getAttachmentName());
                        attachmentDTO.setStatus(j.getStatus());
                        attachmentDTOList.add(attachmentDTO);
                    });
            noticeListVO.setAttachments(attachmentDTOList);
            noticeListVOList.add(noticeListVO);
        });
        pageVO.setRecords(noticeListVOList);

        return pageVO;
    }

    @Override
    public void update(NoticeUpdateDTO noticeUpdateDTO) {
        LambdaUpdateWrapper<FhzgNotice> fhzgNoticeLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        fhzgNoticeLambdaUpdateWrapper.eq(FhzgNotice::getId, noticeUpdateDTO.getId());
        fhzgNoticeLambdaUpdateWrapper.set(noticeUpdateDTO.getStatus() != null, FhzgNotice::getStatus, noticeUpdateDTO.getStatus());
        fhzgNoticeLambdaUpdateWrapper.set(noticeUpdateDTO.getTitle() != null, FhzgNotice::getTitle, noticeUpdateDTO.getTitle());
        fhzgNoticeLambdaUpdateWrapper.set(noticeUpdateDTO.getContent() != null, FhzgNotice::getContent, noticeUpdateDTO.getContent());
        this.update(fhzgNoticeLambdaUpdateWrapper);
    }

    @Override
    @Transactional
    public void add(NoticeAddDTO noticeAddDTO) {
        if (noticeAddDTO.getId() == null && noticeAddDTO.getType() == 0) {
            //文档类型判断标题不能重复
            List<FhzgNotice> list = this.list(new LambdaQueryWrapper<FhzgNotice>().eq(FhzgNotice::getTitle, noticeAddDTO.getTitle()));
            if (!list.isEmpty()) {
                throw new BusinessException("文档标题重复");
            }
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        FhzgNotice fhzgNotice = new FhzgNotice();
        fhzgNotice.setId(noticeAddDTO.getId());
        fhzgNotice.setTitle(noticeAddDTO.getTitle());
        fhzgNotice.setContent(noticeAddDTO.getContent());
        fhzgNotice.setType(noticeAddDTO.getType());
        fhzgNotice.setStatus(noticeAddDTO.getStatus());
        fhzgNotice.setCreateTime(new Date());
        fhzgNotice.setUserId(loginUser.getUserid());
        fhzgNotice.setUserName(loginUser.getUsername());
        this.saveOrUpdate(fhzgNotice);
        if (noticeAddDTO.getAttachments() != null && !noticeAddDTO.getAttachments().isEmpty()) {
            Long id = fhzgNotice.getId();
            List<FhzgNoticeAttachment> fhzgNoticeAttachmentList = new ArrayList<>();
            noticeAttachmentService.remove(new LambdaUpdateWrapper<FhzgNoticeAttachment>().eq(FhzgNoticeAttachment::getNoticeId, id));
            noticeAddDTO.getAttachments().forEach(i -> {
                FhzgNoticeAttachment fhzgNoticeAttachment = new FhzgNoticeAttachment();
                fhzgNoticeAttachment.setNoticeId(id);
                fhzgNoticeAttachment.setAttachmentId(i.getId());
                fhzgNoticeAttachment.setAttachmentName(i.getName());
                fhzgNoticeAttachment.setCreateTime(new Date());
                fhzgNoticeAttachment.setStatus(1);
                fhzgNoticeAttachmentList.add(fhzgNoticeAttachment);
            });
            noticeAttachmentService.saveBatch(fhzgNoticeAttachmentList);
        }
    }

    @Override
    public NoticeVO getDetailById(Long id) {
        FhzgNotice fhzgNotice = this.getById(id);
        if (fhzgNotice == null) {
            return new NoticeVO();
        }
        List<FhzgNoticeAttachment> noticeAttachments = noticeAttachmentService.list(new LambdaQueryWrapper<FhzgNoticeAttachment>().eq(FhzgNoticeAttachment::getNoticeId, id));
        NoticeVO noticeVO = new NoticeVO();
        noticeVO.setId(fhzgNotice.getId());
        noticeVO.setTitle(fhzgNotice.getTitle());
        noticeVO.setContent(fhzgNotice.getContent());
        noticeVO.setType(fhzgNotice.getType());
        noticeVO.setStatus(fhzgNotice.getStatus());
        noticeVO.setCreateTime(fhzgNotice.getCreateTime());
        List<AttachmentDTO> attachmentDTOList = new ArrayList<>();
        noticeAttachments.forEach(i -> {
            AttachmentDTO attachmentDTO = new AttachmentDTO();
            attachmentDTO.setId(i.getAttachmentId());
            attachmentDTO.setSize(i.getFileSize());
            attachmentDTO.setName(i.getAttachmentName());
            attachmentDTO.setStatus(i.getStatus());
            attachmentDTO.setCreateTime(i.getCreateTime());
            attachmentDTOList.add(attachmentDTO);
        });
        noticeVO.setAttachments(attachmentDTOList);
        //记录读取状态
        FhzgNoticeReceiveRecord noticeReceiveRecord = new FhzgNoticeReceiveRecord();
        Long userId = SecurityUtils.getUserId();
        noticeReceiveRecord.setNoticeId(id);
        noticeReceiveRecord.setUserId(userId);
        noticeReceiveRecord.setCreateTime(new Date());
        List<FhzgNoticeReceiveRecord> list = noticeReceiveRecordService.list(new LambdaUpdateWrapper<FhzgNoticeReceiveRecord>()
                .eq(FhzgNoticeReceiveRecord::getNoticeId, id)
                .eq(FhzgNoticeReceiveRecord::getUserId, userId));
        if (list.isEmpty()) {
            noticeReceiveRecordService.save(noticeReceiveRecord);
        }
        return noticeVO;
    }

    @Override
    public void fileUpdate(NoticeUpdateDTO noticeUpdateDTO) {
        List<FhzgNoticeAttachment> fhzgNoticeAttachmentList = new ArrayList<>();
        noticeUpdateDTO.getAttachments().forEach(i -> {
                    FhzgNoticeAttachment fhzgNoticeAttachment = new FhzgNoticeAttachment();
                    fhzgNoticeAttachment.setNoticeId(noticeUpdateDTO.getId());
                    fhzgNoticeAttachment.setAttachmentId(i.getId());
                    fhzgNoticeAttachment.setAttachmentName(i.getName());
                    fhzgNoticeAttachment.setCreateTime(new Date());
                    fhzgNoticeAttachment.setFileSize(i.getSize());
                    fhzgNoticeAttachment.setStatus(1);
                    fhzgNoticeAttachmentList.add(fhzgNoticeAttachment);
                }
        );
        noticeAttachmentService.saveBatch(fhzgNoticeAttachmentList);
    }

    @Override
    public void fileDown(NoticeUpdateDTO noticeUpdateDTO) {
        List<Long> attachmentIds = noticeUpdateDTO.getAttachments().stream().map(AttachmentDTO::getId).collect(Collectors.toList());
        noticeAttachmentService.update(new LambdaUpdateWrapper<FhzgNoticeAttachment>().set(FhzgNoticeAttachment::getStatus, 0)
                .eq(FhzgNoticeAttachment::getNoticeId, noticeUpdateDTO.getId())
                .in(FhzgNoticeAttachment::getAttachmentId, attachmentIds));
        List<FhzgNoticeAttachment> list = noticeAttachmentService.list(new LambdaQueryWrapper<FhzgNoticeAttachment>().eq(FhzgNoticeAttachment::getNoticeId, noticeUpdateDTO.getId()));
        List<FhzgNoticeAttachment> collect = list.stream().filter(i -> i.getStatus() == 1).collect(Collectors.toList());
        if (!list.isEmpty() && collect.isEmpty()) {
            this.update(new LambdaUpdateWrapper<FhzgNotice>().eq(FhzgNotice::getId, noticeUpdateDTO.getId()).set(FhzgNotice::getStatus, 2));
        }
    }

    @Override
    public void delete(NoticeUpdateDTO noticeUpdateDTO) {
        this.removeById(noticeUpdateDTO.getId());
    }

    @Override
    public void fileDelete(NoticeUpdateDTO noticeUpdateDTO) {
        List<Long> attachmentIds = noticeUpdateDTO.getAttachments().stream().map(AttachmentDTO::getId).collect(Collectors.toList());
        LambdaUpdateWrapper<FhzgNoticeAttachment> updateWrapper = new LambdaUpdateWrapper<FhzgNoticeAttachment>();
        updateWrapper.eq(FhzgNoticeAttachment::getNoticeId, noticeUpdateDTO.getId());
        updateWrapper.in(FhzgNoticeAttachment::getAttachmentId, attachmentIds);
        noticeAttachmentService.remove(updateWrapper);
    }

    @Override
    public PageVO<NoticeListVO> getNoticeList(NoticeListDTO noticeListDTO) {
        Long userId = SecurityUtils.getUserId();
        List<NoticeListVO> noticeList = this.baseMapper.getNoticeList(userId, noticeListDTO.getIsRead(), (noticeListDTO.getPageNum() - 1) * noticeListDTO.getPageSize(), noticeListDTO.getPageSize());
        Long noticeListCount = this.baseMapper.getNoticeListCount(userId, noticeListDTO.getIsRead());
        PageVO<NoticeListVO> result = new PageVO<>();
        result.setTotal(noticeListCount);
        result.setRecords(noticeList);
        result.setPageNum(Long.valueOf(noticeListDTO.getPageNum()));
        result.setPageSize(Long.valueOf(noticeListDTO.getPageSize()));
        return result;
    }

    @Override
    public void readAll() {
        Long userId = SecurityUtils.getUserId();
        List<Long> ids = this.baseMapper.getAllUnreadNoticeId(userId);
        List<FhzgNoticeReceiveRecord> noticeReceiveRecords = new ArrayList<>();
        ids.forEach(i -> {
            FhzgNoticeReceiveRecord noticeReceiveRecord = new FhzgNoticeReceiveRecord();
            noticeReceiveRecord.setNoticeId(i);
            noticeReceiveRecord.setUserId(userId);
            noticeReceiveRecord.setCreateTime(new Date());
            noticeReceiveRecords.add(noticeReceiveRecord);
        });
        noticeReceiveRecordService.saveBatch(noticeReceiveRecords);
    }
}




