"""AegisTrade AI Configuration Management."""
from __future__ import annotations

import os
from enum import Enum
from pathlib import Path
from typing import Any


class TradingMode(str, Enum):
    BACKTEST = "BACKTEST"
    PAPER = "PAPER"
    BYBIT_DEMO = "BYBIT_DEMO"
    LIVE = "LIVE"


class Settings:
    """Central configuration for AegisTrade AI with strict security defaults."""

    def __init__(self) -> None:
        self.APP_ENV: str = os.getenv("APP_ENV", "development")
        self.TRADING_MODE: TradingMode = TradingMode(os.getenv("TRADING_MODE", "PAPER").upper())
        self.ENABLE_LIVE_TRADING: bool = os.getenv("ENABLE_LIVE_TRADING", "false").lower() == "true"

        # Security
        self.SECRET_KEY: str = os.getenv("SECRET_KEY", "insecure-dev-key-must-be-changed-in-production-123456")
        self.ACCESS_TOKEN_EXPIRE_MINUTES: int = int(os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES", "1440"))
        self.ADMIN_USERNAME: str = os.getenv("ADMIN_USERNAME", "admin")
        self.ADMIN_PASSWORD: str = os.getenv("ADMIN_PASSWORD", "AegisTradeSafe#2026")

        # Database
        base_dir = Path(__file__).resolve().parent.parent.parent.parent
        default_db_path = base_dir / "data" / "aegistrade.db"
        self.DATABASE_URL: str = os.getenv("DATABASE_URL", f"sqlite:///{default_db_path}")

        # Bybit Demo Credentials (https://api-demo.bybit.com)
        self.BYBIT_DEMO_API_KEY: str = os.getenv("BYBIT_DEMO_API_KEY", "")
        self.BYBIT_DEMO_API_SECRET: str = os.getenv("BYBIT_DEMO_API_SECRET", "")
        self.BYBIT_DEMO_REST_URL: str = os.getenv("BYBIT_DEMO_REST_URL", "https://api-demo.bybit.com")
        self.BYBIT_DEMO_WS_URL: str = os.getenv("BYBIT_DEMO_WS_URL", "wss://stream-demo.bybit.com/v5/private")

        # Bybit Live Credentials (STRICT READ/TRADE ONLY, NO WITHDRAWAL)
        self.BYBIT_LIVE_API_KEY: str = os.getenv("BYBIT_LIVE_API_KEY", "")
        self.BYBIT_LIVE_API_SECRET: str = os.getenv("BYBIT_LIVE_API_SECRET", "")
        self.BYBIT_LIVE_REST_URL: str = os.getenv("BYBIT_LIVE_REST_URL", "https://api.bybit.com")
        self.BYBIT_LIVE_WS_URL: str = os.getenv("BYBIT_LIVE_WS_URL", "wss://stream.bybit.com/v5/private")

        # Public Market Data WebSocket
        self.BYBIT_PUBLIC_WS_URL: str = os.getenv(
            "BYBIT_PUBLIC_WS_URL", "wss://stream.bybit.com/v5/public/linear"
        )

        # Risk Controls & Guardrails (Default Conservative starting profile)
        self.RISK_PER_TRADE_PCT: float = float(os.getenv("RISK_PER_TRADE_PCT", "0.0025"))  # 0.25%
        self.MAX_POSITIONS: int = int(os.getenv("MAX_POSITIONS", "2"))
        self.MAX_DAILY_LOSS_PCT: float = float(os.getenv("MAX_DAILY_LOSS_PCT", "0.010"))  # 1.0%
        self.MAX_DRAWDOWN_PCT: float = float(os.getenv("MAX_DRAWDOWN_PCT", "0.050"))  # 5.0%
        self.MAX_LEVERAGE: float = float(os.getenv("MAX_LEVERAGE", "1.0"))  # 1.0x
        self.MIN_REWARD_TO_RISK: float = float(os.getenv("MIN_REWARD_TO_RISK", "1.5"))
        self.SMALL_ACCOUNT_PROTECTION: bool = (
            os.getenv("SMALL_ACCOUNT_PROTECTION", "true").lower() == "true"
        )

        # Fee & Friction Assumptions
        self.DEFAULT_TAKER_FEE_PCT: float = 0.00055  # 0.055% VIP0 taker
        self.DEFAULT_MAKER_FEE_PCT: float = 0.00020  # 0.02% maker
        self.ESTIMATED_SLIPPAGE_PCT: float = 0.00020  # 0.02%
        self.UNCERTAINTY_BUFFER_PCT: float = 0.00030  # 0.03%

        # Target Symbols Allowlists
        self.ALLOWED_SYMBOLS: list[str] = ["BTCUSDT", "ETHUSDT", "SOLUSDT"]

        # Alerting
        self.TELEGRAM_ALERT_ENABLED: bool = os.getenv("TELEGRAM_ALERT_ENABLED", "false").lower() == "true"
        self.TELEGRAM_BOT_TOKEN: str = os.getenv("TELEGRAM_BOT_TOKEN", "")
        self.TELEGRAM_CHAT_ID: str = os.getenv("TELEGRAM_CHAT_ID", "")

        # Logging
        self.LOG_LEVEL: str = os.getenv("LOG_LEVEL", "INFO")
        self.STRUCTURED_JSON_LOGGING: bool = (
            os.getenv("STRUCTURED_JSON_LOGGING", "true").lower() == "true"
        )

    def validate_safety_invariants(self) -> None:
        """Enforce financial invariants at boot time."""
        if self.TRADING_MODE == TradingMode.LIVE:
            if not self.ENABLE_LIVE_TRADING:
                raise ValueError(
                    "CRITICAL SAFETY VIOLATION: TRADING_MODE is set to LIVE but ENABLE_LIVE_TRADING is False! Aborting."
                )
            if not self.BYBIT_LIVE_API_KEY or not self.BYBIT_LIVE_API_SECRET:
                raise ValueError(
                    "CRITICAL CONFIGURATION ERROR: Live mode selected but live API credentials are empty."
                )
        if self.RISK_PER_TRADE_PCT > 0.02:
            raise ValueError(
                f"SAFETY LIMIT EXCEEDED: Risk per trade {self.RISK_PER_TRADE_PCT*100}% exceeds maximum allowable safety cap of 2.0%."
            )
        if self.MAX_LEVERAGE > 3.0:
            raise ValueError(
                f"SAFETY LIMIT EXCEEDED: Max leverage {self.MAX_LEVERAGE}x exceeds maximum safety limit."
            )


settings = Settings()
