"""Resource Tracker - Monitors API costs, execution time, and compute usage."""

from __future__ import annotations

import json
import uuid
from dataclasses import dataclass
from datetime import datetime
from pathlib import Path
from typing import Any


@dataclass
class ResourceAlert:
    """A resource usage alert."""

    level: str  # warning, critical
    type: str
    message: str
    percent: float


@dataclass
class Operation:
    """A logged operation."""

    id: str
    timestamp: str
    type: str
    description: str
    cost: float = 0.0
    duration: float = 0.0
    tokens: int = 0
    model: str = "unknown"


class ResourceTracker:
    """Tracks resource usage including API costs and execution time."""

    DEFAULT_CONFIG = {
        "budget_hourly": 5.0,  # $5/hour soft limit
        "budget_daily": 50.0,  # $50/day soft limit
        "alert_threshold": 0.8,  # Alert at 80% of budget
    }

    def __init__(
        self,
        db_path: str | None = None,
        budget_hourly: float | None = None,
        budget_daily: float | None = None,
        alert_threshold: float | None = None,
    ) -> None:
        from oclawma.config import get_workspace_dir

        self.db_path = Path(db_path or str(get_workspace_dir() / "memory" / "resource-usage.json"))
        self.budget_hourly = (
            budget_hourly if budget_hourly is not None else self.DEFAULT_CONFIG["budget_hourly"]
        )
        self.budget_daily = (
            budget_daily if budget_daily is not None else self.DEFAULT_CONFIG["budget_daily"]
        )
        self.alert_threshold = (
            alert_threshold
            if alert_threshold is not None
            else self.DEFAULT_CONFIG["alert_threshold"]
        )

    def _init_db(self) -> None:
        """Initialize database if it doesn't exist."""
        if not self.db_path.exists():
            self.db_path.parent.mkdir(parents=True, exist_ok=True)
            self._save_db(
                {
                    "operations": [],
                    "hourlySpent": {},
                    "dailySpent": {},
                    "alerts": [],
                }
            )

    def _load_db(self) -> dict:
        """Load database."""
        try:
            with open(self.db_path, encoding="utf-8") as f:
                return json.load(f)
        except (FileNotFoundError, json.JSONDecodeError):
            return {
                "operations": [],
                "hourlySpent": {},
                "dailySpent": {},
                "alerts": [],
            }

    def _save_db(self, data: dict) -> None:
        """Save database."""
        with open(self.db_path, "w", encoding="utf-8") as f:
            json.dump(data, f, indent=2)

    def _generate_id(self) -> str:
        """Generate a unique ID."""
        return str(uuid.uuid4())[:8]

    def log_operation(
        self,
        op_type: str,
        description: str,
        cost: float = 0.0,
        duration: float = 0.0,
        tokens: int = 0,
        model: str = "unknown",
    ) -> list[ResourceAlert]:
        """Log an operation and check budgets."""
        self._init_db()
        db = self._load_db()

        entry = {
            "id": self._generate_id(),
            "timestamp": datetime.now().isoformat(),
            "type": op_type,
            "description": description,
            "cost": cost,
            "duration": duration,
            "tokens": tokens,
            "model": model,
        }

        db["operations"].append(entry)

        # Update hourly/daily totals
        hour = entry["timestamp"][:13]  # YYYY-MM-DDTHH
        day = entry["timestamp"][:10]  # YYYY-MM-DD

        db["hourlySpent"][hour] = db["hourlySpent"].get(hour, 0) + cost
        db["dailySpent"][day] = db["dailySpent"].get(day, 0) + cost

        self._save_db(db)

        # Check budgets
        return self._check_budgets(db, hour, day)

    def _check_budgets(self, db: dict, current_hour: str, current_day: str) -> list[ResourceAlert]:
        """Check budget status."""
        alerts = []

        hourly = db["hourlySpent"].get(current_hour, 0)
        daily = db["dailySpent"].get(current_day, 0)

        if hourly > self.budget_hourly * self.alert_threshold:
            alerts.append(
                ResourceAlert(
                    level="critical" if hourly > self.budget_hourly else "warning",
                    type="hourly_budget",
                    message=f"Hourly spend: ${hourly:.2f} / ${self.budget_hourly}",
                    percent=(hourly / self.budget_hourly) * 100,
                )
            )

        if daily > self.budget_daily * self.alert_threshold:
            alerts.append(
                ResourceAlert(
                    level="critical" if daily > self.budget_daily else "warning",
                    type="daily_budget",
                    message=f"Daily spend: ${daily:.2f} / ${self.budget_daily}",
                    percent=(daily / self.budget_daily) * 100,
                )
            )

        return alerts

    def get_status(self) -> dict[str, Any]:
        """Get current status."""
        db = self._load_db()
        now = datetime.now()
        hour = now.isoformat()[:13]
        day = now.isoformat()[:10]

        hourly = db["hourlySpent"].get(hour, 0)
        daily = db["dailySpent"].get(day, 0)

        return {
            "hourly": {
                "spent": hourly,
                "budget": self.budget_hourly,
                "percent": (hourly / self.budget_hourly) * 100,
            },
            "daily": {
                "spent": daily,
                "budget": self.budget_daily,
                "percent": (daily / self.budget_daily) * 100,
            },
            "operations": len(db["operations"]),
            "recent": db["operations"][-5:] if db["operations"] else [],
        }

    def generate_report(self) -> None:
        """Generate a full report."""
        db = self._load_db()
        status = self.get_status()

        print("\n╔══════════════════════════════════════════════════════════╗")
        print("║         RESOURCE USAGE REPORT                            ║")
        print("╚══════════════════════════════════════════════════════════╝\n")

        h_icon = (
            "🔴"
            if status["hourly"]["percent"] > 100
            else "🟡" if status["hourly"]["percent"] > 80 else "🟢"
        )
        d_icon = (
            "🔴"
            if status["daily"]["percent"] > 100
            else "🟡" if status["daily"]["percent"] > 80 else "🟢"
        )

        print(
            f"{h_icon} Hourly: ${status['hourly']['spent']:.2f} / ${status['hourly']['budget']} ({status['hourly']['percent']:.1f}%)"
        )
        print(
            f"{d_icon} Daily:  ${status['daily']['spent']:.2f} / ${status['daily']['budget']} ({status['daily']['percent']:.1f}%)\n"
        )

        # Top expensive operations
        top_ops = sorted(db["operations"], key=lambda x: x.get("cost", 0), reverse=True)[:5]

        if top_ops:
            print("💸 Most Expensive Operations:")
            for op in top_ops:
                desc = op["description"][:40]
                print(f"  ${op['cost']:.3f} - {op['type']}: {desc}")

        print(f"\n📊 Total operations logged: {len(db['operations'])}\n")

    def print_status(self) -> None:
        """Print current status."""
        status = self.get_status()
        print(f"Hourly: ${status['hourly']['spent']:.2f} / ${status['hourly']['budget']}")
        print(f"Daily:  ${status['daily']['spent']:.2f} / ${status['daily']['budget']}")
        print(f"Ops:    {status['operations']}")


def main() -> None:
    """CLI entry point."""
    import sys

    tracker = ResourceTracker()
    command = sys.argv[1] if len(sys.argv) > 1 else "status"

    if command == "log":
        op_type = sys.argv[2] if len(sys.argv) > 2 else "operation"
        cost = float(sys.argv[3]) if len(sys.argv) > 3 else 0.0
        desc = " ".join(sys.argv[4:]) if len(sys.argv) > 4 else "Unnamed operation"

        alerts = tracker.log_operation(op_type, desc, cost)
        print(f"✅ Logged: {op_type} (${cost})")
        for alert in alerts:
            icon = "🔴" if alert.level == "critical" else "🟡"
            print(f"{icon} {alert.message}")

    elif command == "status":
        tracker.print_status()

    elif command == "report":
        tracker.generate_report()

    else:
        print("Resource Tracker")
        print("Usage:")
        print("  log [type] [cost] [desc]  - Log an operation")
        print("  status                    - Show current status")
        print("  report                    - Generate full report")


if __name__ == "__main__":
    main()
