import os
import yaml
import threading
import time
from pathlib import Path
from typing import Dict, Any, Optional
from dataclasses import dataclass, field, asdict

@dataclass
class SystemConfig:
    """Authoritative system configuration for ALTRUS"""
    storage_dir: Path = field(default_factory=lambda: Path.home() / ".altrus")
    max_concurrent_intents: int = 5
    intent_timeout_default: float = 30.0
    mttr_threshold: float = 5.0
    ledger_integrity_check_on_load: bool = True
    metrics_port: int = 8000
    bridge_port: int = 5000
    log_level: str = "INFO"

    def __post_init__(self):
        if isinstance(self.storage_dir, str):
            self.storage_dir = Path(self.storage_dir)

class ConfigManager:
    """
    Centralized configuration manager with environment variable overrides
    and optional hot-reload support.
    """
    def __init__(self, config_path: Optional[Path] = None):
        self._config_path = config_path
        self._config = SystemConfig()
        self._lock = threading.Lock()
        self._last_loaded = 0

        self.load()

    def load(self):
        """Load configuration from file and environment"""
        with self._lock:
            # 1. Load from file if exists
            file_data = {}
            if self._config_path and self._config_path.exists():
                with open(self._config_path, "r") as f:
                    file_data = yaml.safe_load(f) or {}
                self._last_loaded = self._config_path.stat().st_mtime

            # 2. Merge with defaults and env overrides
            new_config_dict = asdict(self._config)

            # Apply file data
            for key, value in file_data.items():
                if key in new_config_dict:
                    new_config_dict[key] = value

            # Apply Env overrides
            # Example: ALTRUS_METRICS_PORT=9000
            for key in new_config_dict.keys():
                env_key = f"ALTRUS_{key.upper()}"
                if env_key in os.environ:
                    env_val = os.environ[env_key]
                    # Simple type casting
                    target_type = type(new_config_dict[key])
                    try:
                        if target_type == bool:
                            new_config_dict[key] = env_val.lower() in ("true", "1", "yes")
                        else:
                            new_config_dict[key] = target_type(env_val)
                    except ValueError:
                        print(f"⚠️ Failed to cast env {env_key}={env_val} to {target_type}")

            self._config = SystemConfig(**new_config_dict)
            self._config.storage_dir.mkdir(parents=True, exist_ok=True)

    @property
    def config(self) -> SystemConfig:
        return self._config

    def start_hot_reload(self, interval_seconds: int = 5):
        """Start a background thread to watch for config file changes"""
        if not self._config_path:
            return

        def watch_loop():
            while True:
                time.sleep(interval_seconds)
                if self._config_path.exists():
                    mtime = self._config_path.stat().st_mtime
                    if mtime > self._last_loaded:
                        print(f"🔄 Config file {self._config_path} changed. Reloading...")
                        self.load()

        thread = threading.Thread(target=watch_loop, daemon=True)
        thread.start()
        print(f"👀 Config watcher started for {self._config_path}")
