package com.cameleer.server.app.alerting.eval;

import com.cameleer.server.core.agent.AgentInfo;
import com.cameleer.server.core.agent.AgentRegistryService;
import com.cameleer.server.core.agent.AgentState;
import com.cameleer.server.core.alerting.AgentStateCondition;
import com.cameleer.server.core.alerting.AlertRule;
import com.cameleer.server.core.alerting.AlertScope;
import com.cameleer.server.core.alerting.ConditionKind;
import org.springframework.stereotype.Component;

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

@Component
public class AgentStateEvaluator implements ConditionEvaluator<AgentStateCondition> {

    private final AgentRegistryService registry;

    public AgentStateEvaluator(AgentRegistryService registry) {
        this.registry = registry;
    }

    @Override
    public ConditionKind kind() { return ConditionKind.AGENT_STATE; }

    @Override
    public EvalResult evaluate(AgentStateCondition c, AlertRule rule, EvalContext ctx) {
        AgentState target = AgentState.valueOf(c.state());
        Instant cutoff = ctx.now().minusSeconds(c.forSeconds());

        List<AgentInfo> hits = registry.findAll().stream()
                .filter(a -> matchesScope(a, c.scope()))
                .filter(a -> a.state() == target)
                .filter(a -> a.lastHeartbeat() != null && a.lastHeartbeat().isBefore(cutoff))
                .toList();

        if (hits.isEmpty()) return EvalResult.Clear.INSTANCE;

        AgentInfo first = hits.get(0);
        return new EvalResult.Firing(
                (double) hits.size(), null,
                Map.of(
                        "agent", Map.of(
                                "id",    first.instanceId(),
                                "name",  first.displayName(),
                                "state", first.state().name()
                        ),
                        "app", Map.of("slug", first.applicationId())
                )
        );
    }

    private static boolean matchesScope(AgentInfo a, AlertScope s) {
        if (s == null) return true;
        if (s.appSlug() != null && !s.appSlug().equals(a.applicationId())) return false;
        if (s.agentId() != null && !s.agentId().equals(a.instanceId())) return false;
        return true;
    }
}
