package com.cameleer.server.core.alerting;

import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

public interface AlertInstanceRepository {
    AlertInstance save(AlertInstance instance);   // upsert by id
    Optional<AlertInstance> findById(UUID id);
    Optional<AlertInstance> findOpenForRule(UUID ruleId);  // state IN ('PENDING','FIRING','ACKNOWLEDGED')

    /**
     * Unfiltered inbox listing. Convenience overload that delegates to the filtered
     * variant with {@code states}/{@code severities} set to {@code null} (no filter).
     */
    default List<AlertInstance> listForInbox(UUID environmentId,
                                             List<String> userGroupIdFilter,
                                             String userId,
                                             List<String> userRoleNames,
                                             int limit) {
        return listForInbox(environmentId, userGroupIdFilter, userId, userRoleNames, null, null, limit);
    }

    /**
     * Inbox listing with optional state + severity filters. {@code null} or empty lists mean
     * "no filter on that field". When both lists are non-empty the row must match at least one
     * value from each list (AND between dimensions, OR within).
     */
    List<AlertInstance> listForInbox(UUID environmentId,
                                     List<String> userGroupIdFilter,
                                     String userId,
                                     List<String> userRoleNames,
                                     List<AlertState> states,
                                     List<AlertSeverity> severities,
                                     int limit);

    /**
     * Count unread alert instances for the user, grouped by severity.
     * <p>
     * Always returns a map with an entry for every {@link AlertSeverity} (value 0 if no rows),
     * so callers never need null-checks. Total unread count is the sum of the values.
     */
    Map<AlertSeverity, Long> countUnreadBySeverityForUser(UUID environmentId, String userId);
    void ack(UUID id, String userId, Instant when);
    void resolve(UUID id, Instant when);
    void markSilenced(UUID id, boolean silenced);
    void deleteResolvedBefore(Instant cutoff);

    /** FIRING instances whose reNotify cadence has elapsed since last notification. */
    List<AlertInstance> listFiringDueForReNotify(Instant now);
}
