"""Configuration management for FastAPI Monitor."""

import os
from enum import Enum
from pathlib import Path
from typing import List, Optional

from pydantic import BaseModel, Field, field_validator


class ColorScheme(str, Enum):
    """Available color schemes for the dashboard."""

    DEFAULT = "default"
    COOL = "cool"
    WARM = "warm"


class LogLevel(str, Enum):
    """Available log levels."""

    DEBUG = "DEBUG"
    INFO = "INFO"
    WARNING = "WARNING"
    ERROR = "ERROR"


class MonitorConfig(BaseModel):
    """Configuration for FastAPI Monitor."""

    # Database settings
    db_path: str = Field(default="monitor.db", description="Path to SQLite database")
    db_pool_size: int = Field(default=5, ge=1, le=20, description="Database connection pool size")

    # Middleware settings
    exclude_paths: List[str] = Field(
        default_factory=lambda: ["/monitor", "/health", "/metrics"],
        description="Paths to exclude from monitoring"
    )
    max_request_body_size: int = Field(
        default=1024 * 1024,  # 1MB
        ge=0,
        description="Maximum request body size to capture (bytes)"
    )
    max_response_body_size: int = Field(
        default=1024 * 1024,  # 1MB
        ge=0,
        description="Maximum response body size to capture (bytes)"
    )

    # Dashboard settings
    dashboard_username: Optional[str] = Field(default=None, description="Dashboard username")
    dashboard_password: Optional[str] = Field(default=None, description="Dashboard password")
    color_scheme: ColorScheme = Field(default=ColorScheme.DEFAULT, description="Dashboard color scheme")

    # Performance settings
    request_timeout: float = Field(default=30.0, ge=1.0, description="Request timeout in seconds")
    cleanup_interval: int = Field(default=3600, ge=60, description="Database cleanup interval in seconds")
    max_records: int = Field(default=100000, ge=1000, description="Maximum records to keep in database")

    # Logging
    log_level: LogLevel = Field(default=LogLevel.INFO, description="Logging level")

    @field_validator("db_path")
    @classmethod
    def validate_db_path(cls, v: str) -> str:
        """Validate database path."""
        path = Path(v)
        if path.exists() and not path.is_file():
            raise ValueError(f"Database path {v} exists but is not a file")

        # Ensure parent directory exists
        path.parent.mkdir(parents=True, exist_ok=True)
        return v

    @field_validator("exclude_paths")
    @classmethod
    def validate_exclude_paths(cls, v: List[str]) -> List[str]:
        """Validate exclude paths."""
        return [path.strip() for path in v if path.strip()]

    @classmethod
    def from_env(cls) -> "MonitorConfig":
        """Create configuration from environment variables."""
        env_vars = {}

        # Map environment variables to config fields
        env_mapping = {
            "FASTAPI_MONITOR_DB_PATH": "db_path",
            "FASTAPI_MONITOR_DASHBOARD_USERNAME": "dashboard_username",
            "FASTAPI_MONITOR_DASHBOARD_PASSWORD": "dashboard_password",
            "FASTAPI_MONITOR_COLOR_SCHEME": "color_scheme",
            "FASTAPI_MONITOR_MAX_RECORDS": "max_records",
            "FASTAPI_MONITOR_CLEANUP_INTERVAL": "cleanup_interval",
            "FASTAPI_MONITOR_LOG_LEVEL": "log_level",
        }

        for env_var, field_name in env_mapping.items():
            value = os.getenv(env_var)
            if value is not None:
                # Convert string values to appropriate types
                if field_name in ["max_records", "cleanup_interval"]:
                    value = int(value)
                elif field_name == "request_timeout":
                    value = float(value)
                elif field_name == "exclude_paths":
                    value = [p.strip() for p in value.split(",") if p.strip()]

                env_vars[field_name] = value

        return cls(**env_vars)


def get_config() -> MonitorConfig:
    """Get configuration instance, preferring environment variables."""
    return MonitorConfig.from_env()
