from __future__ import annotations

import ipaddress
from collections import Counter, defaultdict

from .entities import entity_display
from .logs import THREAT_ACTIONS, is_utm_event
from .models import LogEvent
from .normalization import canonical_value


def _entity(event: LogEvent) -> str:
    return event.src_ip or event.fields.get("user") or event.fields.get("username") or event.fields.get("hostname") or event.fields.get("source") or "unknown"


def _display_label(entity: str, events: list[LogEvent]) -> dict[str, str]:
    try:
        ipaddress.ip_address(entity)
    except ValueError:
        return {"entity_display": entity, "entity_label": entity, "entity_detail": ""}
    return entity_display("ip", entity, events)


def build_event_context(events: list[LogEvent], *, source_limit: int = 30, sample_limit: int = 15) -> dict[str, object]:
    grouped: dict[str, list[LogEvent]] = defaultdict(list)
    field_presence: Counter[str] = Counter()
    for event in events:
        grouped[_entity(event)].append(event)
        field_presence.update(event.fields.keys())

    source_profiles = []
    for entity, source_events in grouped.items():
        actions = Counter(event.action or "unknown" for event in source_events)
        destinations = {event.dst_ip for event in source_events if event.dst_ip}
        source_profiles.append({
            "entity": entity, "events": len(source_events), "utm_events": sum(is_utm_event(event) for event in source_events),
            **_display_label(entity, source_events),
            "deny_or_threat_actions": sum(event.action in THREAT_ACTIONS for event in source_events),
            "distinct_destinations": len(destinations), "top_actions": [action for action, _ in actions.most_common(3)],
        })
    source_profiles.sort(key=lambda item: (int(item["utm_events"]) + int(item["deny_or_threat_actions"]), int(item["events"])), reverse=True)

    suspicious = [event for event in events if is_utm_event(event) or event.action in THREAT_ACTIONS or event.severity in {"critical", "high", "alert", "emergency"}]
    samples = [{
        "entity": _entity(event), **_display_label(_entity(event), [event]), "type": canonical_value(event.fields, "type"), "subtype": event.subtype,
        "action": event.action, "severity": event.severity, "dst": event.dst_ip or canonical_value(event.fields, "context"), "service": canonical_value(event.fields, "service"),
        "policyid": event.fields.get("policyid", ""), "timestamp": event.fields.get("eventtime", event.fields.get("timestamp", "")),
    } for event in suspicious[:sample_limit]]
    return {
        "entities_total": len(grouped), "source_profiles": source_profiles[:source_limit],
        "field_coverage": [{"field": field, "events": count} for field, count in field_presence.most_common(30)],
        "security_event_samples": samples,
    }
