"""
Toast Notifications - Temporary status messages

Provides toast notification system with:
- 4 notification types (info, success, warning, error)
- Auto-dismiss with configurable timeout
- Queue management for multiple toasts
- Rich rendering with icons and colors

Examples:
    # Show notification
    notifier = ToastNotifier()
    notifier.info("File saved successfully")
    notifier.error("Connection failed", duration=5.0)

    # Get active toasts for rendering
    toasts = notifier.get_active_toasts()
    for toast in toasts:
        print(toast.render())
"""

from dataclasses import dataclass, field
from datetime import datetime, timedelta
from enum import Enum
from typing import Optional
import time


class ToastType(Enum):
    """Toast notification type"""
    INFO = "info"
    SUCCESS = "success"
    WARNING = "warning"
    ERROR = "error"


@dataclass
class Toast:
    """A toast notification"""
    message: str
    type: ToastType
    created_at: float = field(default_factory=time.time)
    duration: float = 3.0  # seconds
    dismissed: bool = False

    @property
    def icon(self) -> str:
        """Get icon for toast type"""
        icons = {
            ToastType.INFO: "ℹ️",
            ToastType.SUCCESS: "✅",
            ToastType.WARNING: "⚠️",
            ToastType.ERROR: "❌",
        }
        return icons.get(self.type, "ℹ️")

    @property
    def color(self) -> str:
        """Get color code for toast type"""
        colors = {
            ToastType.INFO: "#7dcfff",
            ToastType.SUCCESS: "#9ece6a",
            ToastType.WARNING: "#e0af68",
            ToastType.ERROR: "#f7768e",
        }
        return colors.get(self.type, "#7dcfff")

    @property
    def is_expired(self) -> bool:
        """Check if toast has expired"""
        return time.time() - self.created_at > self.duration

    def render(self, width: int = 60) -> str:
        """
        Render toast notification

        Args:
            width: Maximum width for toast

        Returns:
            Formatted toast string
        """
        # Truncate message if too long
        max_msg_len = width - 4  # Account for icon and padding
        message = self.message[:max_msg_len] if len(self.message) > max_msg_len else self.message

        return f"{self.icon} {message}"

    def dismiss(self):
        """Dismiss this toast"""
        self.dismissed = True


class ToastNotifier:
    """
    Manage toast notifications

    Handles toast queue, auto-dismissal, and rendering.
    Toasts automatically expire after their duration.
    """

    def __init__(self, max_toasts: int = 5):
        """
        Initialize toast notifier

        Args:
            max_toasts: Maximum number of toasts to show at once
        """
        self.max_toasts = max_toasts
        self._toasts: list[Toast] = []

    def _cleanup_expired(self):
        """Remove expired and dismissed toasts"""
        self._toasts = [
            t for t in self._toasts
            if not t.is_expired and not t.dismissed
        ]

    def info(self, message: str, duration: float = 3.0) -> Toast:
        """Show info toast"""
        return self._add_toast(message, ToastType.INFO, duration)

    def success(self, message: str, duration: float = 3.0) -> Toast:
        """Show success toast"""
        return self._add_toast(message, ToastType.SUCCESS, duration)

    def warning(self, message: str, duration: float = 4.0) -> Toast:
        """Show warning toast"""
        return self._add_toast(message, ToastType.WARNING, duration)

    def error(self, message: str, duration: float = 5.0) -> Toast:
        """Show error toast"""
        return self._add_toast(message, ToastType.ERROR, duration)

    def _add_toast(self, message: str, type: ToastType, duration: float) -> Toast:
        """Add a toast to the queue"""
        self._cleanup_expired()

        toast = Toast(message=message, type=type, duration=duration)
        self._toasts.append(toast)

        # Limit number of active toasts
        if len(self._toasts) > self.max_toasts:
            self._toasts.pop(0)

        return toast

    def get_active_toasts(self) -> list[Toast]:
        """Get all active toasts"""
        self._cleanup_expired()
        return list(self._toasts)

    def dismiss_all(self):
        """Dismiss all active toasts"""
        for toast in self._toasts:
            toast.dismiss()
        self._cleanup_expired()

    def count(self) -> int:
        """Get number of active toasts"""
        self._cleanup_expired()
        return len(self._toasts)

    def render_all(self, width: int = 60) -> list[str]:
        """
        Render all active toasts

        Args:
            width: Maximum width for each toast

        Returns:
            List of rendered toast strings
        """
        self._cleanup_expired()
        return [toast.render(width) for toast in self._toasts]


# Convenience functions

def create_notifier(max_toasts: int = 5) -> ToastNotifier:
    """
    Create a toast notifier

    Args:
        max_toasts: Maximum number of toasts to show at once

    Returns:
        ToastNotifier instance
    """
    return ToastNotifier(max_toasts=max_toasts)
