"""
Formatting utilities for display.
"""

from datetime import datetime
from typing import Optional, Union


def format_date(
    value: Optional[Union[str, datetime]],
    length: int = 10,
    include_time: bool = False,
) -> str:
    """
    Format a date/datetime for display.

    Args:
        value: Date string or datetime object
        length: Length to truncate to (default 10 for YYYY-MM-DD)
        include_time: Whether to include time portion

    Returns:
        Formatted date string
    """
    if value is None:
        return ""

    if isinstance(value, str):
        # Parse ISO format string
        try:
            if "T" in value:
                dt = datetime.fromisoformat(value.replace("Z", "+00:00"))
            else:
                return value[:length]
        except ValueError:
            return value[:length]
    else:
        dt = value

    if include_time:
        return dt.strftime("%Y-%m-%d %H:%M")
    return dt.strftime("%Y-%m-%d")


def format_size(size_bytes: Optional[int]) -> str:
    """
    Format file size in human-readable form.

    Args:
        size_bytes: Size in bytes

    Returns:
        Human-readable size string (e.g., "1.5 MB")
    """
    if size_bytes is None:
        return "Unknown"
    if size_bytes < 0:
        return "Unknown"
    if size_bytes == 0:
        return "0 B"

    units = ["B", "KB", "MB", "GB", "TB"]
    unit_index = 0
    size = float(size_bytes)

    while size >= 1024 and unit_index < len(units) - 1:
        size /= 1024
        unit_index += 1

    if unit_index == 0:
        return f"{int(size)} {units[unit_index]}"
    return f"{size:.1f} {units[unit_index]}"


def truncate_hash(value: str, length: int = 16, suffix: str = "...") -> str:
    """
    Truncate a hash or long string with ellipsis.

    Args:
        value: String to truncate
        length: Maximum length before truncation
        suffix: Suffix to add when truncated

    Returns:
        Truncated string
    """
    if not value:
        return ""
    if len(value) <= length:
        return value
    return f"{value[:length]}{suffix}"


def format_duration(seconds: Optional[float]) -> str:
    """
    Format duration in human-readable form.

    Args:
        seconds: Duration in seconds

    Returns:
        Human-readable duration string (e.g., "2m 30s")
    """
    if seconds is None or seconds < 0:
        return "Unknown"

    if seconds < 1:
        return f"{int(seconds * 1000)}ms"

    if seconds < 60:
        return f"{seconds:.1f}s"

    minutes = int(seconds // 60)
    remaining_seconds = int(seconds % 60)

    if minutes < 60:
        if remaining_seconds:
            return f"{minutes}m {remaining_seconds}s"
        return f"{minutes}m"

    hours = minutes // 60
    remaining_minutes = minutes % 60

    if remaining_minutes:
        return f"{hours}h {remaining_minutes}m"
    return f"{hours}h"


def format_count(count: int) -> str:
    """
    Format a count with abbreviation for large numbers.

    Args:
        count: Number to format

    Returns:
        Formatted string (e.g., "1.2K", "3.5M")
    """
    if count < 1000:
        return str(count)
    if count < 1000000:
        return f"{count / 1000:.1f}K"
    if count < 1000000000:
        return f"{count / 1000000:.1f}M"
    return f"{count / 1000000000:.1f}B"


def format_percentage(value: float, decimals: int = 1) -> str:
    """
    Format a percentage value.

    Args:
        value: Percentage value (0-100 or 0-1)
        decimals: Number of decimal places

    Returns:
        Formatted percentage string
    """
    # Assume 0-1 if less than 1
    if value <= 1:
        value *= 100

    if decimals == 0:
        return f"{int(value)}%"
    return f"{value:.{decimals}f}%"
