package com.ga.api.service.notice;

import com.ga.common.exception.BizException;
import com.ga.common.exception.ErrorCode;
import com.ga.common.model.PageResponse;
import com.ga.common.util.SecurityUtil;
import com.ga.core.mapper.notice.NoticeMapper;
import com.ga.core.mapper.notice.UserNotificationMapper;
import com.ga.core.vo.notice.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class NoticeService {

    private final NoticeMapper noticeMapper;
    private final UserNotificationMapper notificationMapper;

    // ── Notice ────────────────────────────────────────────────────────────────

    public PageResponse<NoticeResp> list(NoticeSearchParam param) {
        param.startPage();
        return PageResponse.of(noticeMapper.selectList(param));
    }

    public NoticeResp detail(Long noticeId) {
        NoticeResp resp = noticeMapper.selectById(noticeId);
        if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
        return resp;
    }

    public List<NoticeResp> activeList() {
        return noticeMapper.selectActive();
    }

    @Transactional
    public Long create(NoticeSaveReq req) {
        NoticeVO vo = new NoticeVO();
        vo.setTitle(req.getTitle());
        vo.setContent(req.getContent());
        vo.setNoticeType(req.getNoticeType());
        vo.setStartDate(req.getStartDate());
        vo.setEndDate(req.getEndDate());
        vo.setIsActive(true);
        vo.setCreatedBy(SecurityUtil.getCurrentUserId());
        noticeMapper.insert(vo);
        return vo.getNoticeId();
    }

    @Transactional
    public void update(Long noticeId, NoticeSaveReq req) {
        NoticeResp existing = noticeMapper.selectById(noticeId);
        if (existing == null) throw new BizException(ErrorCode.NOT_FOUND);
        NoticeVO vo = new NoticeVO();
        vo.setNoticeId(noticeId);
        vo.setTitle(req.getTitle());
        vo.setContent(req.getContent());
        vo.setNoticeType(req.getNoticeType());
        vo.setStartDate(req.getStartDate());
        vo.setEndDate(req.getEndDate());
        noticeMapper.update(vo);
    }

    @Transactional
    public void delete(Long noticeId) {
        NoticeResp existing = noticeMapper.selectById(noticeId);
        if (existing == null) throw new BizException(ErrorCode.NOT_FOUND);
        noticeMapper.delete(noticeId);
    }

    // ── UserNotification ──────────────────────────────────────────────────────

    public PageResponse<UserNotificationResp> listNotifications(UserNotificationSearchParam param) {
        param.startPage();
        return PageResponse.of(notificationMapper.selectList(param));
    }

    public int unreadCount(Long userId) {
        return notificationMapper.selectUnreadCount(userId);
    }

    @Transactional
    public void markRead(Long notificationId, Long userId) {
        int affected = notificationMapper.markRead(notificationId, userId);
        if (affected == 0) throw new BizException(ErrorCode.NOT_FOUND);
    }

    @Transactional
    public void markAllRead(Long userId) {
        notificationMapper.markAllRead(userId);
    }
}
