# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""Causal Crew Composer public API. Helpers in crew_helpers.py, checks in crew_checks.py."""
from __future__ import annotations
import logging
from pulse.daemons.synthesis.swarm.crew_helpers import (  # noqa: F401
    _COMPLEXITY_TIER, _TIER_RANK, _tier_covers, get_pending_tasks, _query_graph_risks,
)
from pulse.daemons.synthesis.swarm.crew_checks import (  # noqa: F401
    OLLAMA_FREE_LIMIT, _check_agent_weaknesses, _score_tier_alignment,
    _check_provider_limits, _check_epistemic_conflict,
)

log = logging.getLogger("pulse.crew_composer")


def score_crew(crew, tasks=None):
    """Score crew via Tier Alignment + graph risks + provider limits."""
    if tasks is None:
        tasks = get_pending_tasks()
    if not crew:
        return {"score": 0.0, "warnings": ["No agents in crew"], "suggestions": [], "task_summary": {}}
    domains = {t.get("domain", "general") for t in tasks}
    warnings = []
    suggestions = []
    tier_score, tier_warnings = _score_tier_alignment(crew, tasks)
    warnings.extend(tier_warnings)
    provider_penalty, provider_warnings, is_ollama_only = _check_provider_limits(crew)
    warnings.extend(provider_warnings)
    graph_risks = _query_graph_risks(domains)
    cause_risks = [r for r in graph_risks if r["type"] == "cause"]
    protections = [r for r in graph_risks if r["type"] == "protection"]
    for risk in cause_risks[:3]:
        warnings.append(
            risk["domain"] + ": " + risk["text"] + " (" + risk["relationship"]
            + ", confidence: " + format(risk['confidence'], '.0%') + ")"
        )
    risk_penalty = len(cause_risks) * 0.05
    protection_bonus = min(len(protections) * 0.03, 0.1)
    agent_warnings = _check_agent_weaknesses(crew, domains)
    for aw in agent_warnings[:2]:
        warnings.append(
            "Agent " + aw["agent"] + " has " + format(aw['success_rate'], '.0%')
            + " success on " + aw["domain"] + " (" + str(aw["total"]) + " tasks)"
        )
    weakness_penalty = len(agent_warnings) * 0.05
    if any("high-complexity" in w.lower() for w in tier_warnings):
        if is_ollama_only:
            suggestions.append("High-complexity tasks need premium tier — Ollama cloud models are free premium options")
        else:
            suggestions.append("Add 1x premium-tier agent for high-complexity oversight")
    if any("only fast" in w.lower() for w in tier_warnings):
        if is_ollama_only:
            suggestions.append("Swap 1x fast agent for an Ollama cloud model (standard+)")
        else:
            suggestions.append("Add 1x standard-tier agent for medium-complexity tasks")
    if any("waste tokens" in w.lower() for w in tier_warnings):
        suggestions.append("Replace premium agents with fast-tier for cost savings")
    if any("ollama free plan" in w.lower() for w in provider_warnings):
        suggestions.append("Reduce Ollama agents to " + str(OLLAMA_FREE_LIMIT) + " or upgrade Ollama plan")
    for aw in agent_warnings[:1]:
        suggestions.append("Consider replacing " + aw["agent"] + " — weak on " + aw["domain"] + " tasks")
    epistemic_warnings = _check_epistemic_conflict(crew, tasks)
    warnings.extend(epistemic_warnings)
    epistemic_penalty = len(epistemic_warnings) * 0.15
    for _ in epistemic_warnings:
        suggestions.append("Swap conflicting agents to align crew worldview.")
    final_score = max(0.0, min(1.0,
        tier_score - risk_penalty + protection_bonus - epistemic_penalty
        - weakness_penalty - provider_penalty))
    complexity_counts = {}
    domain_counts = {}
    for t in tasks:
        c = t.get("complexity", "low"); d = t.get("domain", "general")
        complexity_counts[c] = complexity_counts.get(c, 0) + 1
        domain_counts[d] = domain_counts.get(d, 0) + 1
    return {
        "score": round(final_score, 2), "warnings": warnings, "suggestions": suggestions,
        "task_summary": {"total": len(tasks), "by_complexity": complexity_counts, "by_domain": domain_counts},
        "graph_risks": len(cause_risks), "graph_protections": len(protections), "ollama_only": is_ollama_only,
    }


def format_crew_analysis(analysis):
    """Format crew analysis for CLI display."""
    score = analysis.get("score", 0.5)
    warnings = analysis.get("warnings", [])
    suggestions = analysis.get("suggestions", [])
    summary = analysis.get("task_summary", {})
    label = "LOW RISK" if score >= 0.7 else ("MODERATE RISK" if score >= 0.4 else "HIGH RISK")
    lines = ["", "  --- CREW ANALYSIS ---", "  Score: " + f"{score:.2f}/1.0 ({label})"]
    total = summary.get("total", 0)
    if total > 0:
        domain_parts = [str(c) + " " + d for d, c in summary.get("by_domain", {}).items()]
        lines.append("  Pending tasks: " + str(total) + " (" + ", ".join(domain_parts) + ")")
    if warnings:
        lines.append("")
        for w in warnings[:4]:
            lines.append("  !  " + w)
    if suggestions:
        lines.append("")
        for s in suggestions[:3]:
            lines.append("  +  " + s)
    lines.append("  " + "-" * 40)
    return chr(10).join(lines)
