from __future__ import annotations

from typing import Any, Dict, List, Optional


def _round_amount(value: Any) -> float:
    try:
        return round(float(value or 0.0), 6)
    except (TypeError, ValueError):
        return 0.0


def _int(value: Any) -> int:
    try:
        return int(value or 0)
    except (TypeError, ValueError):
        return 0


def _asset_feed_entry(entry: Any) -> Optional[Dict[str, Any]]:
    if not isinstance(entry, dict):
        return None
    state = str(entry.get("state") or "").strip()
    if state not in {"live", "deprecated", "archived"}:
        return None
    return {
        "state": state,
        "state_key": str(entry.get("state_key") or "").strip(),
        "asset_id": str(entry.get("asset_id") or "").strip(),
        "file_path": str(entry.get("file_path") or "").strip(),
        "suggested_name": str(entry.get("suggested_name") or "").strip(),
        "asset_class": str(entry.get("asset_class") or "").strip(),
        "price_model": str(entry.get("price_model") or "").strip(),
        "portfolio_policy_reason": str(entry.get("portfolio_policy_reason") or "").strip(),
        "reason": str(entry.get("reason") or "").strip(),
        "updated_at": _int(entry.get("updated_at")),
        "executed_by": entry.get("executed_by"),
        "recommended_by": entry.get("recommended_by"),
    }


def build_portfolio_outcome_summary(
    *,
    runtime_identity: Optional[Dict[str, Any]] = None,
    ledger_summary: Optional[Dict[str, Any]] = None,
    lifecycle_summary: Optional[Dict[str, Any]] = None,
    delegate_limit: int = 6,
) -> Dict[str, Any]:
    runtime_identity = dict(runtime_identity or {})
    ledger_summary = dict(ledger_summary or {})
    lifecycle_summary = dict(lifecycle_summary or {})

    principal = dict(runtime_identity.get("principal") or {})
    account = dict(runtime_identity.get("account") or {})
    ledger_totals = dict(ledger_summary.get("totals") or {})
    lifecycle_counts = dict(lifecycle_summary.get("counts") or {})
    lifecycle_recent = list(lifecycle_summary.get("recent") or [])
    contribution_groups = dict(ledger_summary.get("contributions") or {})
    delegate_rows = list(contribution_groups.get("delegates") or [])

    principal_result = {
        "principal_id": str(principal.get("id") or "").strip(),
        "carrier_type": str(principal.get("carrier_type") or "").strip(),
        "account_id": str(account.get("id") or "").strip(),
        "spent_oas": _round_amount(ledger_totals.get("spent_oas")),
        "earned_oas": _round_amount(ledger_totals.get("earned_oas")),
        "net_oas": _round_amount(ledger_totals.get("net_oas")),
        "successful_actions": _int(ledger_totals.get("succeeded")),
        "failed_actions": _int(ledger_totals.get("failed")),
        "assets_created": _int(ledger_totals.get("assets_created")),
        "purchases": _int(ledger_totals.get("purchases")),
        "live_assets": _int(lifecycle_counts.get("live")),
        "deprecated_assets": _int(lifecycle_counts.get("deprecated")),
        "archived_assets": _int(lifecycle_counts.get("archived")),
    }

    asset_outcomes = {
        "observed": _int(lifecycle_counts.get("observed")),
        "candidate": _int(lifecycle_counts.get("candidate")),
        "draft": _int(lifecycle_counts.get("draft")),
        "live": _int(lifecycle_counts.get("live")),
        "deprecated": _int(lifecycle_counts.get("deprecated")),
        "archived": _int(lifecycle_counts.get("archived")),
        "created": _int(ledger_totals.get("assets_created")),
        "failed_actions": _int(ledger_totals.get("failed")),
    }

    delegate_contributions: List[Dict[str, Any]] = []
    for row in delegate_rows[:delegate_limit]:
        agent_counts = dict(row.get("agent_counts") or {})
        top_agents = [
            {"agent_id": str(agent_id), "count": _int(count)}
            for agent_id, count in list(agent_counts.items())[:3]
        ]
        delegate_contributions.append(
            {
                "principal_id": str(row.get("principal_id") or "").strip(),
                "delegate_id": str(row.get("delegate_id") or "").strip(),
                "executions": _int(row.get("executions")),
                "succeeded": _int(row.get("succeeded")),
                "failed": _int(row.get("failed")),
                "spent_oas": _round_amount(row.get("spent_oas")),
                "earned_oas": _round_amount(row.get("earned_oas")),
                "net_oas": _round_amount(row.get("net_oas")),
                "assets_created": _int(row.get("assets_created")),
                "purchases": _int(row.get("purchases")),
                "last_timestamp": _int(row.get("last_timestamp")),
                "agent_counts": agent_counts,
                "top_agents": top_agents,
            }
        )

    asset_feed = [
        candidate
        for candidate in (_asset_feed_entry(entry) for entry in lifecycle_recent)
        if candidate
    ]

    return {
        "principal_result": principal_result,
        "asset_outcomes": asset_outcomes,
        "delegate_contributions": delegate_contributions,
        "asset_feed": asset_feed,
    }
