# Auto-generated by DjangoCFG - see CLAUDE.md

"""
API Logger with Rich
Beautiful console logging for API requests and responses

Installation:
    pip install rich
"""

from __future__ import annotations

import time
from dataclasses import dataclass, field
from typing import Any

from rich.console import Console
from rich.panel import Panel
from rich.table import Table
from rich.text import Text


@dataclass
class RequestLog:
    """Request log data."""

    method: str
    url: str
    headers: dict[str, str] | None = None
    body: Any | None = None
    timestamp: float = field(default_factory=time.time)


@dataclass
class ResponseLog:
    """Response log data."""

    status: int
    status_text: str
    data: Any | None = None
    duration: float = 0.0
    timestamp: float = field(default_factory=time.time)


@dataclass
class ErrorLog:
    """Error log data."""

    message: str
    status_code: int | None = None
    field_errors: dict[str, list[str]] | None = None
    duration: float = 0.0
    timestamp: float = field(default_factory=time.time)


@dataclass
class LoggerConfig:
    """Logger configuration."""

    enabled: bool = True
    log_requests: bool = True
    log_responses: bool = True
    log_errors: bool = True
    log_bodies: bool = True
    log_headers: bool = False
    console: Console | None = None


# Sensitive header names to filter out
SENSITIVE_HEADERS = [
    "authorization",
    "cookie",
    "set-cookie",
    "x-api-key",
    "x-csrf-token",
]


class APILogger:
    """API Logger class."""

    def __init__(self, config: LoggerConfig | None = None):
        """Initialize logger."""
        self.config = config or LoggerConfig()
        self.console = self.config.console or Console()

    def enable(self) -> None:
        """Enable logging."""
        self.config.enabled = True

    def disable(self) -> None:
        """Disable logging."""
        self.config.enabled = False

    def set_config(self, **kwargs: Any) -> None:
        """Update configuration."""
        for key, value in kwargs.items():
            if hasattr(self.config, key):
                setattr(self.config, key, value)

    def _filter_headers(self, headers: dict[str, str] | None) -> dict[str, str]:
        """Filter sensitive headers."""
        if not headers:
            return {}

        filtered = {}
        for key, value in headers.items():
            if key.lower() in SENSITIVE_HEADERS:
                filtered[key] = "***"
            else:
                filtered[key] = value

        return filtered

    def log_request(self, request: RequestLog) -> None:
        """Log request."""
        if not self.config.enabled or not self.config.log_requests:
            return

        # Create request info
        text = Text()
        text.append("→ ", style="bold blue")
        text.append(request.method, style="bold yellow")
        text.append(" ", style="")
        text.append(request.url, style="cyan")

        self.console.print(text)

        if self.config.log_headers and request.headers:
            headers = self._filter_headers(request.headers)
            self.console.print("  Headers:", style="dim")
            for key, value in headers.items():
                self.console.print(f"    {key}: {value}", style="dim")

        if self.config.log_bodies and request.body:
            self.console.print("  Body:", style="dim")
            self.console.print(request.body, style="dim")

    def log_response(self, request: RequestLog, response: ResponseLog) -> None:
        """Log response."""
        if not self.config.enabled or not self.config.log_responses:
            return

        # Determine color based on status
        if response.status >= 500:
            status_style = "bold red"
        elif response.status >= 400:
            status_style = "bold yellow"
        elif response.status >= 300:
            status_style = "bold cyan"
        else:
            status_style = "bold green"

        # Create response info
        text = Text()
        text.append("← ", style="bold green")
        text.append(request.method, style="bold yellow")
        text.append(" ", style="")
        text.append(request.url, style="cyan")
        text.append(" ", style="")
        text.append(str(response.status), style=status_style)
        text.append(" ", style="")
        text.append(response.status_text, style=status_style)
        text.append(f" ({response.duration:.0f}ms)", style="dim")

        self.console.print(text)

        if self.config.log_bodies and response.data:
            self.console.print("  Response:", style="dim")
            self.console.print(response.data, style="dim")

    def log_error(self, request: RequestLog, error: ErrorLog) -> None:
        """Log error."""
        if not self.config.enabled or not self.config.log_errors:
            return

        # Create error header
        text = Text()
        text.append("✗ ", style="bold red")
        text.append(request.method, style="bold yellow")
        text.append(" ", style="")
        text.append(request.url, style="cyan")
        text.append(" ", style="")
        text.append(
            str(error.status_code) if error.status_code else "Network",
            style="bold red",
        )
        text.append(" Error", style="bold red")
        text.append(f" ({error.duration:.0f}ms)", style="dim")

        self.console.print(text)
        self.console.print(f"  Message: {error.message}", style="red")

        if error.field_errors:
            self.console.print("  Field Errors:", style="red")
            for field, errors in error.field_errors.items():
                for err in errors:
                    self.console.print(f"    • {field}: {err}", style="red dim")

    def info(self, message: str, **kwargs: Any) -> None:
        """Log info message."""
        if not self.config.enabled:
            return
        self.console.print(f"ℹ {message}", style="blue", **kwargs)

    def warn(self, message: str, **kwargs: Any) -> None:
        """Log warning message."""
        if not self.config.enabled:
            return
        self.console.print(f"⚠ {message}", style="yellow", **kwargs)

    def error(self, message: str, **kwargs: Any) -> None:
        """Log error message."""
        if not self.config.enabled:
            return
        self.console.print(f"✗ {message}", style="red", **kwargs)

    def success(self, message: str, **kwargs: Any) -> None:
        """Log success message."""
        if not self.config.enabled:
            return
        self.console.print(f"✓ {message}", style="green", **kwargs)

    def debug(self, message: str, **kwargs: Any) -> None:
        """Log debug message."""
        if not self.config.enabled:
            return
        self.console.print(f"🔍 {message}", style="dim", **kwargs)

    def panel(self, content: Any, title: str, style: str = "blue") -> None:
        """Log content in a panel."""
        if not self.config.enabled:
            return
        self.console.print(Panel(content, title=title, border_style=style))

    def table(
        self,
        headers: list[str],
        rows: list[list[Any]],
        title: str | None = None,
    ) -> None:
        """Log data in a table."""
        if not self.config.enabled:
            return

        table = Table(title=title)
        for header in headers:
            table.add_column(header, style="cyan")

        for row in rows:
            table.add_row(*[str(cell) for cell in row])

        self.console.print(table)


# Default logger instance
default_logger = APILogger()