package com.cameleer.server.core.alerting;

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

public record AlertInstance(
        UUID id,
        UUID ruleId,                // nullable after rule deletion
        Map<String, Object> ruleSnapshot,
        UUID environmentId,
        AlertState state,
        AlertSeverity severity,
        Instant firedAt,
        Instant ackedAt,
        String ackedBy,
        Instant resolvedAt,
        Instant lastNotifiedAt,
        Instant readAt,             // NEW — global "someone has seen this"
        Instant deletedAt,          // NEW — soft delete
        boolean silenced,
        Double currentValue,
        Double threshold,
        Map<String, Object> context,
        String title,
        String message,
        List<String> targetUserIds,
        List<UUID> targetGroupIds,
        List<String> targetRoleNames) {

    public AlertInstance {
        ruleSnapshot    = ruleSnapshot    == null ? Map.of()  : Map.copyOf(ruleSnapshot);
        context         = context         == null ? Map.of()  : Map.copyOf(context);
        targetUserIds   = targetUserIds   == null ? List.of() : List.copyOf(targetUserIds);
        targetGroupIds  = targetGroupIds  == null ? List.of() : List.copyOf(targetGroupIds);
        targetRoleNames = targetRoleNames == null ? List.of() : List.copyOf(targetRoleNames);
    }

    // --- Wither helpers (return a new record with one field changed) ---

    public AlertInstance withState(AlertState s) {
        return new AlertInstance(id, ruleId, ruleSnapshot, environmentId,
                s, severity, firedAt, ackedAt, ackedBy, resolvedAt, lastNotifiedAt, readAt, deletedAt, silenced,
                currentValue, threshold, context, title, message,
                targetUserIds, targetGroupIds, targetRoleNames);
    }

    public AlertInstance withFiredAt(Instant i) {
        return new AlertInstance(id, ruleId, ruleSnapshot, environmentId,
                state, severity, i, ackedAt, ackedBy, resolvedAt, lastNotifiedAt, readAt, deletedAt, silenced,
                currentValue, threshold, context, title, message,
                targetUserIds, targetGroupIds, targetRoleNames);
    }

    public AlertInstance withResolvedAt(Instant i) {
        return new AlertInstance(id, ruleId, ruleSnapshot, environmentId,
                state, severity, firedAt, ackedAt, ackedBy, i, lastNotifiedAt, readAt, deletedAt, silenced,
                currentValue, threshold, context, title, message,
                targetUserIds, targetGroupIds, targetRoleNames);
    }

    public AlertInstance withAck(String ackedBy, Instant ackedAt) {
        return new AlertInstance(id, ruleId, ruleSnapshot, environmentId,
                state, severity, firedAt, ackedAt, ackedBy, resolvedAt, lastNotifiedAt, readAt, deletedAt, silenced,
                currentValue, threshold, context, title, message,
                targetUserIds, targetGroupIds, targetRoleNames);
    }

    public AlertInstance withSilenced(boolean silenced) {
        return new AlertInstance(id, ruleId, ruleSnapshot, environmentId,
                state, severity, firedAt, ackedAt, ackedBy, resolvedAt, lastNotifiedAt, readAt, deletedAt, silenced,
                currentValue, threshold, context, title, message,
                targetUserIds, targetGroupIds, targetRoleNames);
    }

    public AlertInstance withTitleMessage(String title, String message) {
        return new AlertInstance(id, ruleId, ruleSnapshot, environmentId,
                state, severity, firedAt, ackedAt, ackedBy, resolvedAt, lastNotifiedAt, readAt, deletedAt, silenced,
                currentValue, threshold, context, title, message,
                targetUserIds, targetGroupIds, targetRoleNames);
    }

    public AlertInstance withLastNotifiedAt(Instant instant) {
        return new AlertInstance(id, ruleId, ruleSnapshot, environmentId,
                state, severity, firedAt, ackedAt, ackedBy, resolvedAt, instant, readAt, deletedAt, silenced,
                currentValue, threshold, context, title, message,
                targetUserIds, targetGroupIds, targetRoleNames);
    }

    public AlertInstance withContext(Map<String, Object> context) {
        return new AlertInstance(id, ruleId, ruleSnapshot, environmentId,
                state, severity, firedAt, ackedAt, ackedBy, resolvedAt, lastNotifiedAt, readAt, deletedAt, silenced,
                currentValue, threshold, context, title, message,
                targetUserIds, targetGroupIds, targetRoleNames);
    }

    public AlertInstance withRuleSnapshot(Map<String, Object> snapshot) {
        return new AlertInstance(id, ruleId, snapshot, environmentId,
                state, severity, firedAt, ackedAt, ackedBy, resolvedAt, lastNotifiedAt, readAt, deletedAt, silenced,
                currentValue, threshold, context, title, message,
                targetUserIds, targetGroupIds, targetRoleNames);
    }

    public AlertInstance withReadAt(Instant i) {
        return new AlertInstance(id, ruleId, ruleSnapshot, environmentId,
                state, severity, firedAt, ackedAt, ackedBy, resolvedAt, lastNotifiedAt, i, deletedAt, silenced,
                currentValue, threshold, context, title, message,
                targetUserIds, targetGroupIds, targetRoleNames);
    }

    public AlertInstance withDeletedAt(Instant i) {
        return new AlertInstance(id, ruleId, ruleSnapshot, environmentId,
                state, severity, firedAt, ackedAt, ackedBy, resolvedAt, lastNotifiedAt, readAt, i, silenced,
                currentValue, threshold, context, title, message,
                targetUserIds, targetGroupIds, targetRoleNames);
    }
}
