"""Cooling period tracker."""

import json
from datetime import datetime, timedelta
from pathlib import Path
from typing import Any

from ..config import Config


class CooldownTracker:
    """Track cooling periods for purchase intentions."""

    def __init__(self):
        """Initialize cooldown tracker."""
        self.data_dir = Config.get_data_dir()
        self.cooldowns_file = self.data_dir / "cooldowns.json"
        self._ensure_file_exists()

    def _ensure_file_exists(self) -> None:
        """Ensure the cooldowns file exists."""
        if not self.cooldowns_file.exists():
            self._save_cooldowns({})

    def _load_cooldowns(self) -> dict[str, dict[str, Any]]:
        """Load cooldowns from file."""
        try:
            with open(self.cooldowns_file, "r") as f:
                return json.load(f)
        except (json.JSONDecodeError, FileNotFoundError):
            return {}

    def _save_cooldowns(self, cooldowns: dict[str, dict[str, Any]]) -> None:
        """Save cooldowns to file."""
        with open(self.cooldowns_file, "w") as f:
            json.dump(cooldowns, f, indent=2)

    def add_cooldown(self, symbol: str, hours: int) -> dict[str, Any]:
        """Add a cooldown for a symbol."""
        cooldowns = self._load_cooldowns()

        now = datetime.now()
        expires = now + timedelta(hours=hours)

        cooldowns[symbol.upper()] = {
            "symbol": symbol.upper(),
            "started": now.isoformat(),
            "expires": expires.isoformat(),
            "hours": hours,
        }

        self._save_cooldowns(cooldowns)

        return cooldowns[symbol.upper()]

    def remove_cooldown(self, symbol: str) -> bool:
        """Remove a cooldown for a symbol."""
        cooldowns = self._load_cooldowns()

        if symbol.upper() in cooldowns:
            del cooldowns[symbol.upper()]
            self._save_cooldowns(cooldowns)
            return True
        return False

    def get_cooldown(self, symbol: str) -> dict[str, Any] | None:
        """Get cooldown info for a symbol."""
        cooldowns = self._load_cooldowns()
        cooldown = cooldowns.get(symbol.upper())

        if not cooldown:
            return None

        # Check if expired
        expires = datetime.fromisoformat(cooldown["expires"])
        if datetime.now() >= expires:
            self.remove_cooldown(symbol)
            return None

        return self._format_cooldown(cooldown)

    def get_active_cooldowns(self) -> list[dict[str, Any]]:
        """Get all active (non-expired) cooldowns."""
        cooldowns = self._load_cooldowns()
        active = []
        expired_symbols = []

        now = datetime.now()

        for symbol, cooldown in cooldowns.items():
            expires = datetime.fromisoformat(cooldown["expires"])
            if now >= expires:
                expired_symbols.append(symbol)
            else:
                active.append(self._format_cooldown(cooldown))

        # Clean up expired cooldowns
        if expired_symbols:
            for symbol in expired_symbols:
                del cooldowns[symbol]
            self._save_cooldowns(cooldowns)

        return sorted(active, key=lambda x: x["expires"])

    def is_in_cooldown(self, symbol: str) -> bool:
        """Check if a symbol is in cooldown."""
        return self.get_cooldown(symbol) is not None

    def _format_cooldown(self, cooldown: dict[str, Any]) -> dict[str, Any]:
        """Format cooldown for display."""
        started = datetime.fromisoformat(cooldown["started"])
        expires = datetime.fromisoformat(cooldown["expires"])
        now = datetime.now()

        remaining = expires - now
        remaining_hours = remaining.total_seconds() / 3600

        if remaining_hours >= 24:
            remaining_str = f"{remaining_hours / 24:.1f} days"
        elif remaining_hours >= 1:
            remaining_str = f"{remaining_hours:.1f} hours"
        else:
            remaining_minutes = remaining.total_seconds() / 60
            remaining_str = f"{remaining_minutes:.0f} minutes"

        return {
            "symbol": cooldown["symbol"],
            "started": started.strftime("%Y-%m-%d %H:%M"),
            "expires": expires.strftime("%Y-%m-%d %H:%M"),
            "remaining": remaining_str,
            "remaining_seconds": remaining.total_seconds(),
        }

    def extend_cooldown(self, symbol: str, additional_hours: int) -> dict[str, Any] | None:
        """Extend an existing cooldown."""
        cooldowns = self._load_cooldowns()
        cooldown = cooldowns.get(symbol.upper())

        if not cooldown:
            return None

        expires = datetime.fromisoformat(cooldown["expires"])
        new_expires = expires + timedelta(hours=additional_hours)

        cooldowns[symbol.upper()]["expires"] = new_expires.isoformat()
        cooldowns[symbol.upper()]["hours"] += additional_hours

        self._save_cooldowns(cooldowns)

        return self._format_cooldown(cooldowns[symbol.upper()])
