from collections import Counter
from typing import Dict, List, Optional

import click

from cleancloud.core.finding import Finding


def build_summary(
    findings: List[Finding], skipped_rules: Optional[List[dict]] = None
) -> Dict[str, object]:
    by_provider = Counter(f.provider for f in findings)
    by_risk = Counter(f.risk for f in findings)
    by_confidence = Counter(f.confidence for f in findings)

    costed_findings = [f for f in findings if f.estimated_monthly_cost_usd is not None]
    total_cost = sum(f.estimated_monthly_cost_usd for f in costed_findings)

    summary: Dict[str, object] = {
        "total_findings": len(findings),
        "by_provider": dict(by_provider),
        "by_risk": dict(by_risk),
        "by_confidence": dict(by_confidence),
    }

    if total_cost > 0:
        summary["minimum_estimated_monthly_waste_usd"] = round(total_cost, 2)
        summary["findings_with_cost_estimate"] = len(costed_findings)

    if skipped_rules:
        summary["skipped_rules"] = skipped_rules

    return summary


def _format_enum_counts(data: dict) -> dict[str, int]:
    result = {}
    for key, value in data.items():
        if hasattr(key, "value"):
            result[key.value] = value
        else:
            result[str(key)] = value
    return result


def _print_summary(summary: dict, region_selection_mode: str = None):
    click.echo("\n--- Scan Summary ---")

    skipped_rules = summary.get("skipped_rules", [])
    total_rules = 10  # fixed number of rules per provider
    executed = total_rules - len(skipped_rules)
    if skipped_rules:
        click.echo(f"Rules executed: {executed}/{total_rules}")
        click.echo(f"Rules skipped:  {len(skipped_rules)} (missing permissions)")
    click.echo(f"Total findings: {summary['total_findings']}")

    # By risk
    by_risk = _format_enum_counts(summary.get("by_risk", {}))
    if by_risk:
        click.echo("\nBy risk:")
        for risk in sorted(by_risk):
            click.echo(f"  {risk}: {by_risk[risk]}")

    # By confidence
    by_conf = _format_enum_counts(summary.get("by_confidence", {}))
    if by_conf:
        click.echo("\nBy confidence:")
        for conf in sorted(by_conf):
            click.echo(f"  {conf}: {by_conf[conf]}")

    # Regions/Subscriptions scanned
    regions_scanned = summary.get("regions_scanned", [])
    if isinstance(regions_scanned, list):
        regions_str = ", ".join(regions_scanned)
    else:
        regions_str = str(regions_scanned)

    # Use provider-aware label
    provider = summary.get("provider", "aws")
    if provider == "azure":
        label = "Subscriptions scanned"
    else:
        label = "Regions scanned"

    click.echo(f"\n{label}: {regions_str}", nl=False)

    # Selection mode annotations
    if provider == "azure":
        if region_selection_mode == "all":
            click.echo(" (all accessible)")
        elif region_selection_mode == "explicit":
            click.echo(" (explicit)")
        else:
            click.echo()
    else:  # AWS
        if region_selection_mode == "all-regions":
            click.echo(" (auto-detected)")
        elif region_selection_mode == "explicit":
            click.echo(" (explicit)")
        else:
            click.echo()

    # Estimated monthly waste
    waste = summary.get("minimum_estimated_monthly_waste_usd")
    if waste and waste > 0:
        costed = summary.get("findings_with_cost_estimate", 0)
        total = summary.get("total_findings", 0)
        click.echo(f"\nMinimum estimated waste: ~${waste:,.0f}/month")
        click.echo(f"({costed} of {total} findings costed)")

    click.echo(f"Scanned at: {summary['scanned_at']}")

    # Tag filtering visibility
    if summary.get("ignored_by_tag_policy", 0) > 0:
        click.echo(f"Ignored by tag policy: {summary['ignored_by_tag_policy']}")

    # Skipped rules detail
    if skipped_rules:
        click.echo()
        click.echo("Skipped (missing permissions):")
        for skipped in skipped_rules:
            rule_name = skipped["rule"]
            if rule_name.startswith("find_"):
                rule_name = rule_name[5:]
            missing = skipped.get("missing_permissions", "")
            # Strip verbose prefix if present
            missing = missing.replace("Missing required IAM permissions: ", "")
            click.echo(f"  - {rule_name}")
            if missing:
                click.echo(f"      needs: {missing}")
        click.echo()
        click.echo(
            "Run 'cleancloud doctor --provider <aws|azure>' to see how to grant full coverage."
        )

    # Success message
    if summary["total_findings"] == 0:
        click.echo()
        click.echo("No hygiene issues detected")
        click.echo()
