"""Application configuration classes for MES Dashboard."""

from __future__ import annotations

import os
from typing import Type


def _int_env(name: str, default: int) -> int:
    try:
        return int(os.getenv(name, str(default)))
    except (TypeError, ValueError):
        return default


def _float_env(name: str, default: float) -> float:
    try:
        return float(os.getenv(name, str(default)))
    except (TypeError, ValueError):
        return default


def _bool_env(name: str, default: bool) -> bool:
    value = os.getenv(name)
    if value is None:
        return default
    return value.strip().lower() in {"1", "true", "yes", "on"}


class Config:
    """Base configuration."""

    DEBUG = False
    TESTING = False
    ENV = "production"

    # Database pool defaults (can be overridden by env)
    DB_POOL_SIZE = _int_env("DB_POOL_SIZE", 5)
    DB_MAX_OVERFLOW = _int_env("DB_MAX_OVERFLOW", 10)
    DB_POOL_TIMEOUT = _int_env("DB_POOL_TIMEOUT", 30)
    DB_POOL_RECYCLE = _int_env("DB_POOL_RECYCLE", 1800)
    DB_TCP_CONNECT_TIMEOUT = _int_env("DB_TCP_CONNECT_TIMEOUT", 10)
    DB_CONNECT_RETRY_COUNT = _int_env("DB_CONNECT_RETRY_COUNT", 1)
    DB_CONNECT_RETRY_DELAY = _float_env("DB_CONNECT_RETRY_DELAY", 1.0)
    DB_CALL_TIMEOUT_MS = _int_env("DB_CALL_TIMEOUT_MS", 55000)

    # Auth configuration - MUST be set in .env file
    LDAP_API_URL = os.getenv("LDAP_API_URL", "")
    ADMIN_EMAILS = os.getenv("ADMIN_EMAILS", "")
    SECRET_KEY = os.getenv("SECRET_KEY")
    CSRF_ENABLED = _bool_env("CSRF_ENABLED", True)
    PORTAL_SPA_ENABLED = _bool_env("PORTAL_SPA_ENABLED", True)

    # Session configuration
    PERMANENT_SESSION_LIFETIME = _int_env("SESSION_LIFETIME", 28800)  # 8 hours

    # Realtime Equipment Status Cache
    REALTIME_EQUIPMENT_CACHE_ENABLED = os.getenv(
        "REALTIME_EQUIPMENT_CACHE_ENABLED", "true"
    ).lower() in ("true", "1", "yes")
    EQUIPMENT_STATUS_SYNC_INTERVAL = _int_env("EQUIPMENT_STATUS_SYNC_INTERVAL", 300)  # 5 minutes

    # Workcenter Mapping Cache
    WORKCENTER_MAPPING_SYNC_INTERVAL = _int_env("WORKCENTER_MAPPING_SYNC_INTERVAL", 86400)  # 24 hours


class DevelopmentConfig(Config):
    """Development configuration."""

    DEBUG = True
    ENV = "development"

    # Smaller pool to ensure keep-alive covers all connections
    DB_POOL_SIZE = _int_env("DB_POOL_SIZE", 2)
    DB_MAX_OVERFLOW = _int_env("DB_MAX_OVERFLOW", 3)
    DB_POOL_TIMEOUT = _int_env("DB_POOL_TIMEOUT", 30)
    DB_POOL_RECYCLE = _int_env("DB_POOL_RECYCLE", 1800)
    DB_TCP_CONNECT_TIMEOUT = _int_env("DB_TCP_CONNECT_TIMEOUT", 10)
    DB_CONNECT_RETRY_COUNT = _int_env("DB_CONNECT_RETRY_COUNT", 1)
    DB_CONNECT_RETRY_DELAY = _float_env("DB_CONNECT_RETRY_DELAY", 1.0)
    DB_CALL_TIMEOUT_MS = _int_env("DB_CALL_TIMEOUT_MS", 55000)


class ProductionConfig(Config):
    """Production configuration."""

    DEBUG = False
    ENV = "production"

    DB_POOL_SIZE = _int_env("DB_POOL_SIZE", 10)
    DB_MAX_OVERFLOW = _int_env("DB_MAX_OVERFLOW", 20)
    DB_POOL_TIMEOUT = _int_env("DB_POOL_TIMEOUT", 30)
    DB_POOL_RECYCLE = _int_env("DB_POOL_RECYCLE", 1800)
    DB_TCP_CONNECT_TIMEOUT = _int_env("DB_TCP_CONNECT_TIMEOUT", 10)
    DB_CONNECT_RETRY_COUNT = _int_env("DB_CONNECT_RETRY_COUNT", 1)
    DB_CONNECT_RETRY_DELAY = _float_env("DB_CONNECT_RETRY_DELAY", 1.0)
    DB_CALL_TIMEOUT_MS = _int_env("DB_CALL_TIMEOUT_MS", 55000)


class TestingConfig(Config):
    """Testing configuration."""

    DEBUG = True
    TESTING = True
    ENV = "testing"

    DB_POOL_SIZE = 1
    DB_MAX_OVERFLOW = 0
    DB_POOL_TIMEOUT = 5
    DB_POOL_RECYCLE = 300
    DB_TCP_CONNECT_TIMEOUT = 5
    DB_CONNECT_RETRY_COUNT = 0
    DB_CONNECT_RETRY_DELAY = 0.0
    DB_CALL_TIMEOUT_MS = 5000
    CSRF_ENABLED = False


def get_config(env: str | None = None) -> Type[Config]:
    """Select config class based on environment name."""
    value = (env or os.getenv("FLASK_ENV", "development")).lower()
    if value in {"prod", "production"}:
        return ProductionConfig
    if value in {"test", "testing"}:
        return TestingConfig
    return DevelopmentConfig
