package com.writeoff.module.notification.service;

import com.writeoff.common.api.PageResult;
import com.writeoff.common.exception.BusinessException;
import com.writeoff.module.notification.model.InAppNotificationInfo;
import com.writeoff.security.AuthContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class InAppNotificationService {
    private final JdbcTemplate jdbcTemplate;

    private static final RowMapper<InAppNotificationInfo> ROW_MAPPER = (rs, n) -> new InAppNotificationInfo(
            rs.getLong("id"),
            rs.getString("title"),
            rs.getString("content"),
            rs.getString("status"),
            rs.getString("created_at"),
            rs.getString("read_at")
    );

    public InAppNotificationService(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public PageResult<InAppNotificationInfo> listMine() {
        Long userId = AuthContext.userId();
        String userRef = userId == null ? "" : ("user-" + userId);
        List<InAppNotificationInfo> list = jdbcTemplate.query(
                "SELECT id, title, content, status, " +
                        "DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') AS created_at, " +
                        "DATE_FORMAT(read_at, '%Y-%m-%d %H:%i:%s') AS read_at " +
                        "FROM in_app_notification " +
                        "WHERE tenant_id=? AND is_deleted=0 AND (receiver_ref='ALL' OR receiver_ref=? OR receiver_user_id=?) " +
                        "ORDER BY id DESC LIMIT 200",
                ROW_MAPPER,
                tenantId(),
                userRef,
                userId
        );
        return new PageResult<InAppNotificationInfo>(list, list.size(), 1, 200);
    }

    @Transactional(rollbackFor = Exception.class)
    public void markRead(Long id) {
        Long userId = AuthContext.userId();
        String userRef = userId == null ? "" : ("user-" + userId);
        Integer count = jdbcTemplate.queryForObject(
                "SELECT COUNT(1) FROM in_app_notification " +
                        "WHERE tenant_id=? AND id=? AND is_deleted=0 AND (receiver_ref='ALL' OR receiver_ref=? OR receiver_user_id=?)",
                Integer.class,
                tenantId(),
                id,
                userRef,
                userId
        );
        if (count == null || count == 0) {
            throw new BusinessException(10003, "站内通知不存在");
        }
        jdbcTemplate.update(
                "UPDATE in_app_notification SET status='READ', read_at=CURRENT_TIMESTAMP, updated_at=CURRENT_TIMESTAMP, updated_by=? WHERE tenant_id=? AND id=?",
                safeUserId(),
                tenantId(),
                id
        );
    }

    @Transactional(rollbackFor = Exception.class)
    public int markAllRead() {
        Long userId = AuthContext.userId();
        String userRef = userId == null ? "" : ("user-" + userId);
        return jdbcTemplate.update(
                "UPDATE in_app_notification SET status='READ', read_at=CURRENT_TIMESTAMP, updated_at=CURRENT_TIMESTAMP, updated_by=? " +
                        "WHERE tenant_id=? AND is_deleted=0 AND status='UNREAD' AND (receiver_ref='ALL' OR receiver_ref=? OR receiver_user_id=?)",
                safeUserId(),
                tenantId(),
                userRef,
                userId
        );
    }

    private Long safeUserId() {
        Long userId = AuthContext.userId();
        return userId == null ? 0L : userId;
    }

    private Long tenantId() {
        return AuthContext.requireTenantId();
    }
}
