"""Toil estimation calculator."""

from __future__ import annotations

from typing import List

import yaml

from sre_beacon.models import ToilFrequency, ToilReport, ToilTask


# Multiplier to convert frequency to monthly occurrences
_FREQ_TO_MONTHLY = {
    ToilFrequency.HOURLY: 30 * 8,      # ~8 working hours/day × 30 days
    ToilFrequency.DAILY: 22,            # working days
    ToilFrequency.WEEKLY: 4.33,
    ToilFrequency.MONTHLY: 1,
    ToilFrequency.QUARTERLY: 1 / 3,
}


def load_toil_tasks(path: str) -> List[ToilTask]:
    """Load toil task definitions from a YAML file.

    Expected format::

        engineering_hours_per_month: 160
        tasks:
          - name: Restart stuck pods
            frequency: daily
            duration_minutes: 15
            automatable: true
            category: kubernetes
    """
    with open(path, "r", encoding="utf-8") as fh:
        data = yaml.safe_load(fh)

    tasks: List[ToilTask] = []
    for entry in data.get("tasks", []):
        tasks.append(
            ToilTask(
                name=entry["name"],
                frequency=ToilFrequency(entry.get("frequency", "weekly")),
                duration_minutes=int(entry.get("duration_minutes", 15)),
                automatable=bool(entry.get("automatable", True)),
                category=entry.get("category", "general"),
                description=entry.get("description", ""),
            )
        )
    return tasks


def calculate_toil(
    tasks: List[ToilTask],
    engineering_hours_per_month: float = 160.0,
) -> ToilReport:
    """Calculate toil metrics from a list of tasks."""
    total_hours = 0.0
    automatable_hours = 0.0
    by_category: dict = {}
    by_frequency: dict = {}

    for task in tasks:
        monthly_occurrences = _FREQ_TO_MONTHLY.get(task.frequency, 1)
        task_hours = (task.duration_minutes * monthly_occurrences) / 60.0

        total_hours += task_hours
        if task.automatable:
            automatable_hours += task_hours

        # Category aggregation
        cat = task.category
        if cat not in by_category:
            by_category[cat] = {"hours": 0.0, "tasks": 0, "automatable_hours": 0.0}
        by_category[cat]["hours"] += task_hours
        by_category[cat]["tasks"] += 1
        if task.automatable:
            by_category[cat]["automatable_hours"] += task_hours

        # Frequency aggregation
        freq = task.frequency.value
        if freq not in by_frequency:
            by_frequency[freq] = {"hours": 0.0, "tasks": 0}
        by_frequency[freq]["hours"] += task_hours
        by_frequency[freq]["tasks"] += 1

    # Round values
    for cat_data in by_category.values():
        cat_data["hours"] = round(cat_data["hours"], 1)
        cat_data["automatable_hours"] = round(cat_data["automatable_hours"], 1)
    for freq_data in by_frequency.values():
        freq_data["hours"] = round(freq_data["hours"], 1)

    toil_pct = (total_hours / engineering_hours_per_month * 100.0) if engineering_hours_per_month > 0 else 0
    auto_pct = (automatable_hours / total_hours * 100.0) if total_hours > 0 else 0

    return ToilReport(
        tasks=tasks,
        total_toil_hours_per_month=round(total_hours, 1),
        toil_percentage=round(toil_pct, 1),
        automatable_hours_per_month=round(automatable_hours, 1),
        automation_potential_pct=round(auto_pct, 1),
        by_category=by_category,
        by_frequency=by_frequency,
        engineering_hours_per_month=engineering_hours_per_month,
    )


def toil_health(report: ToilReport) -> dict:
    """Assess toil health and provide recommendations."""
    status = "healthy"
    recommendations = []

    if report.toil_percentage > 50:
        status = "critical"
        recommendations.append("Toil exceeds 50% — team is in survival mode. Urgent automation needed.")
    elif report.toil_percentage > 30:
        status = "warning"
        recommendations.append("Toil exceeds 30% — approaching unsustainable levels.")
    elif report.toil_percentage > 15:
        status = "watch"
        recommendations.append("Toil is above 15% — start prioritizing automation projects.")

    if report.automation_potential_pct > 70:
        recommendations.append(
            f"{report.automation_potential_pct:.0f}% of toil is automatable — "
            f"could save {report.automatable_hours_per_month:.0f}h/month."
        )

    # Find largest toil category
    if report.by_category:
        worst_cat = max(report.by_category.items(), key=lambda x: x[1]["hours"])
        recommendations.append(
            f"Biggest toil category: '{worst_cat[0]}' at {worst_cat[1]['hours']:.1f}h/month."
        )

    return {"status": status, "recommendations": recommendations}
