import json
from pydantic_settings import BaseSettings
from typing import List, Any, Dict, Optional, Union
from pydantic import Field, field_validator, ValidationError


class Settings(BaseSettings):
    # Service Settings
    SERVICE_NAME: str = Field(default="Google Search Service", description="Name of the service")
    VERSION: str = Field(default="1.0.0", description="Version of the service")

    # Kafka Settings
    # Kafka Settings - Using Union to handle string or list input
    KAFKA_BOOTSTRAP_SERVERS: Union[str, List[str]] = Field(
        default="kafka:29092", 
        description="Kafka bootstrap servers (comma-separated string or JSON list)",
        env="KAFKA_BOOTSTRAP_SERVERS"
    )
    # KAFKA_CONSUMER_GROUP: str = Field(default="google-search-group", description="Kafka consumer group name")
    KAFKA_CONSUMER_GROUP: str = Field(default="search-coordinator-group", description="Kafka consumer group name", env="KAFKA_CONSUMER_GROUP")
    
    GOOGLE_QUEUE_TOPIC: str = Field(default="google-search-queue", description="Queue topic for Google searches")

    # Search Settings
    MAX_RESULTS_PER_SEARCH: int = Field(default=20, description="Maximum number of results per search")
    SEARCH_TIMEOUT: int = Field(default=30, description="Timeout for Google search in seconds")
    
    # Selenium Settings
    HEADLESS_BROWSER: bool = Field(default=True, description="Whether to run browser in headless mode")
    BROWSER_TIMEOUT: int = Field(default=60, description="Timeout for browser operations in seconds")
    
    class Config:
        env_file = ".env"
        case_sensitive = True
        env_file_encoding = 'utf-8'

    @field_validator('KAFKA_BOOTSTRAP_SERVERS')
    @classmethod
    def validate_kafka_bootstrap_servers(cls, value):
        """Validate and normalize Kafka bootstrap servers."""
        # Handle None or empty values
        if value is None or value == "":
            return ["kafka:9092"]
        
        # If it's already a list, return it
        if isinstance(value, list):
            return [server.strip() for server in value if server.strip()] or ["kafka:9092"]
        
        # If it's a string, process it
        if isinstance(value, str):
            value = value.strip()
            
            # Handle empty string after stripping
            if not value:
                return ["kafka:9092"]
            
            # Handle comma-separated values
            if "," in value:
                servers = [server.strip() for server in value.split(",") if server.strip()]
                return servers if servers else ["kafka:9092"]
            
            # Handle JSON string
            if value.startswith('[') and value.endswith(']'):
                try:
                    parsed = json.loads(value)
                    if isinstance(parsed, list):
                        return [str(server).strip() for server in parsed if str(server).strip()] or ["kafka:9092"]
                except json.JSONDecodeError:
                    pass
            
            # Single server
            return [value]
        
        # Fallback to default
        return ["kafka:9092"]

    @property
    def kafka_bootstrap_servers_list(self) -> List[str]:
        """Get Kafka bootstrap servers as a list."""
        if isinstance(self.KAFKA_BOOTSTRAP_SERVERS, list):
            return self.KAFKA_BOOTSTRAP_SERVERS
        return [self.KAFKA_BOOTSTRAP_SERVERS]

    @property
    def kafka_config(self) -> Dict[str, Any]:
        """Get Kafka configuration."""
        return {
            "bootstrap_servers": self.kafka_bootstrap_servers_list,  
        }
        
# Instantiate settings with better error handling
try:
    settings = Settings()
    print(f"✅ Settings loaded successfully!")
    print(f"🔧 SERVICE_NAME: {settings.SERVICE_NAME}")
    print(f"🗄️  ERVICE_VERSION: {settings.VERSION}")
    print(f"📡 Kafka Bootstrap Servers: {settings.kafka_bootstrap_servers_list}")
except ValidationError as e:
    print("❌ Validation Error loading settings:")
    for error in e.errors():
        field = '.'.join(str(loc) for loc in error['loc'])
        print(f"  - {field}: {error['msg']}")
        if 'input' in error:
            print(f"    Input value: {repr(error['input'])}")
    raise
except Exception as e:
    print(f"❌ Unexpected error loading settings: {e}")
    raise