from __future__ import annotations

from typing import Any

from app.algorithem.employee_behavior_profile import build_review_suggestions
from app.models.employee_behavior_profile import EmployeeBehaviorProfileSnapshot


def build_profile_payloads(
    rows: list[EmployeeBehaviorProfileSnapshot],
) -> list[dict[str, Any]]:
    return [
        {
            "profile_type": row.profile_type,
            "profile_label": row.profile_type,
            "score": row.profile_score,
            "level": row.profile_level,
            "metrics": row.metrics_json or {},
            "top_contributors": row.basis_codes_json or [],
        }
        for row in sorted(rows, key=lambda item: item.profile_type)
    ]


def build_latest_review_suggestions(
    *,
    rows: list[EmployeeBehaviorProfileSnapshot],
    expense_score: int,
    process_score: int,
) -> list[dict[str, Any]]:
    expense_row = next((row for row in rows if row.profile_type == "expense"), None)
    metrics = expense_row.metrics_json if expense_row is not None else {}
    formula_suggestions = build_review_suggestions(
        expense_profile_score=expense_score,
        process_quality_score=process_score,
        requested_days=metrics.get("requested_days"),
        peer_days_p75=metrics.get("peer_days_p75"),
        peer_unit_amount_p75=metrics.get("peer_unit_amount_p75"),
    )
    merged = [*formula_suggestions, *_merge_review_suggestions(rows)]
    seen: set[str] = set()
    unique: list[dict[str, Any]] = []
    for item in merged:
        key = str(item.get("type") or item.get("message") or "").strip()
        if not key or key in seen:
            continue
        seen.add(key)
        unique.append(item)
    return unique[:5]


def _merge_review_suggestions(
    rows: list[EmployeeBehaviorProfileSnapshot],
) -> list[dict[str, Any]]:
    merged: list[dict[str, Any]] = []
    seen: set[str] = set()
    for row in rows:
        for suggestion in (row.metrics_json or {}).get("review_suggestions") or []:
            key = str(suggestion.get("type") or suggestion.get("message") or "")
            if key and key not in seen:
                seen.add(key)
                merged.append(suggestion)
    return merged[:5]
