from __future__ import annotations

from collections import Counter, defaultdict


def _severity(score: int) -> str:
    return "critical" if score >= 85 else "high" if score >= 60 else "medium" if score >= 35 else "low"


def build_triage_queue(
    incidents: list[dict[str, object]],
    field_deviations: dict[str, list[dict[str, object]]],
    correlations: list[dict[str, object]],
    recommendations: list[object],
    *,
    limit: int = 25,
) -> list[dict[str, object]]:
    """Summarize raw findings into analyst-sized investigation candidates."""
    groups: dict[str, dict[str, object]] = defaultdict(lambda: {
        "entity": "",
        "entity_display": "",
        "entity_label": "",
        "entity_detail": "",
        "score": 0,
        "streams": set(),
        "detectors": Counter(),
        "evidence": [],
        "deviations": 0,
        "reviewed": Counter(),
        "correlated_streams": 0,
        "recommendations": [],
        "incident_id": "",
        "state": "open",
    })
    for incident in incidents:
        entity = str(incident.get("entity", ""))
        if not entity:
            continue
        group = groups[entity]
        group["entity"] = entity
        group["entity_display"] = str(incident.get("entity_display") or group["entity_display"] or entity)
        group["entity_label"] = str(incident.get("entity_label") or group["entity_label"] or group["entity_display"] or entity)
        group["entity_detail"] = str(incident.get("entity_detail") or group["entity_detail"] or "")
        group["score"] = max(int(group["score"]), int(incident.get("score", 0) or 0))
        group["incident_id"] = str(incident.get("id", ""))
        group["state"] = str(incident.get("lifecycle_status", "open") or "open")
        group["streams"].update(str(item) for item in incident.get("correlated_streams", []) if item)
        group["evidence"].extend(str(item) for item in incident.get("evidence", []) if item)
    for entity, deviations in field_deviations.items():
        group = groups[str(entity)]
        group["entity"] = str(entity)
        active_scores = []
        for item in deviations:
            status = str(item.get("feedback", "unreviewed") or "unreviewed")
            group["reviewed"][status] += 1
            group["deviations"] = int(group["deviations"]) + 1
            group["streams"].add(str(item.get("stream_name") or item.get("stream_title") or item.get("stream_id", "")))
            group["detectors"][str(item.get("detector", "unknown"))] += 1
            if status in {"expected", "false_positive"}:
                continue
            score = int(item.get("score", 0) or 0)
            active_scores.append(score)
            group["evidence"].append(str(item.get("reason", "")))
        if active_scores:
            group["score"] = max(int(group["score"]), max(active_scores))
    for correlation in correlations:
        entity = str(correlation.get("entity") or correlation.get("source_ip") or "")
        if not entity:
            continue
        group = groups[entity]
        group["entity"] = entity
        group["entity_display"] = str(correlation.get("entity_display") or group["entity_display"] or entity)
        group["entity_label"] = str(correlation.get("entity_label") or group["entity_label"] or group["entity_display"] or entity)
        group["entity_detail"] = str(correlation.get("entity_detail") or group["entity_detail"] or "")
        streams = [str(item) for item in correlation.get("streams", []) if item]
        group["streams"].update(streams)
        group["correlated_streams"] = max(int(group["correlated_streams"]), len(streams))
        if len(streams) > 1:
            group["score"] = max(int(group["score"]), min(100, 25 + len(streams) * 8 + int(correlation.get("security_events", 0) or 0) * 2))
            group["evidence"].append(f"activity observed across {len(streams)} streams")
    for recommendation in recommendations:
        subject = str(getattr(recommendation, "subject", ""))
        if not subject:
            continue
        group = groups[subject]
        group["entity"] = subject
        group["score"] = max(int(group["score"]), int(getattr(recommendation, "score", 0) or 0))
        group["recommendations"].append(str(getattr(recommendation, "title", "")))

    queue = []
    for group in groups.values():
        score = int(group["score"])
        if score <= 0:
            continue
        reviewed = group["reviewed"]
        active = int(group["deviations"]) - int(reviewed.get("expected", 0)) - int(reviewed.get("false_positive", 0))
        if active <= 0 and score < 60:
            continue
        detectors = group["detectors"].most_common(3)
        evidence = list(dict.fromkeys(str(item) for item in group["evidence"] if item))[:4]
        next_action = "confirm or suppress expected behavior"
        if int(group["correlated_streams"]) > 1:
            next_action = "investigate cross-source activity"
        if reviewed.get("confirmed"):
            next_action = "follow confirmed incident response"
        queue.append({
            "entity": group["entity"],
            "entity_display": group["entity_display"] or group["entity"],
            "entity_label": group["entity_label"] or group["entity_display"] or group["entity"],
            "entity_detail": group["entity_detail"],
            "score": score,
            "severity": _severity(score),
            "state": group["state"],
            "incident_id": group["incident_id"],
            "streams": sorted(item for item in group["streams"] if item),
            "detectors": [name for name, _count in detectors],
            "deviation_count": int(group["deviations"]),
            "active_deviation_count": active,
            "reviewed": dict(reviewed),
            "evidence": evidence,
            "recommendations": [item for item in group["recommendations"] if item][:3],
            "next_action": next_action,
        })
    return sorted(queue, key=lambda item: (int(item["score"]), int(item["active_deviation_count"])), reverse=True)[:limit]
