"""
Configuration module for {{ agent_display_name }}
Centralizes all environment variables and configuration settings
"""

import os
import json
from pathlib import Path
from typing import Optional

from a2a.types import AgentCard
from abi_core.common.agent_card_loader import load_agent_card


class AgentConfig:
    """Configuration class for {{ agent_display_name }}"""
    
    # Agent Identity
    AGENT_NAME: str = "{{ agent_name }}"
    AGENT_DISPLAY_NAME: str = "{{ agent_display_name }}"
    AGENT_DESCRIPTION: str = "{{ agent_description }}"
    
    # Ports
    AGENT_PORT: int = int(os.getenv('AGENT_PORT', '{{ agent_port }}'))
    SERVICE_PORT: int = int(os.getenv('SERVICE_PORT', '{{ agent_port }}'))
    {% if with_web_interface %}
    WEB_INTERFACE_PORT: int = int(os.getenv('WEB_INTERFACE_PORT', '{{ web_interface_port }}'))
    {% endif %}
    
    # Model Configuration
    MODEL_NAME: str = os.getenv('MODEL_NAME', '{{ model_name }}')
    OLLAMA_HOST: str = os.getenv('OLLAMA_HOST', 'http://{{ project_dir }}-ollama:11434')
    
    # LLM Configuration (unified dict for create_llm)
    LLM_CONFIG: dict = {
        "provider": os.getenv("LLM_PROVIDER", "ollama"),
        "model": os.getenv("MODEL_NAME", "{{ model_name }}"),
        "temperature": float(os.getenv("LLM_TEMPERATURE", "0.1")),
        "base_url": os.getenv("LLM_BASE_URL", os.getenv("OLLAMA_HOST", "http://{{ project_dir }}-ollama:11434")),
        "api_key": os.getenv("LLM_API_KEY", ""),
        # Cloud-specific (only used when provider requires them)
        "aws_region": os.getenv("AWS_REGION", "us-east-1"),
        "azure_deployment": os.getenv("AZURE_DEPLOYMENT", ""),
        "azure_endpoint": os.getenv("AZURE_ENDPOINT", ""),
        "vertex_project": os.getenv("VERTEX_PROJECT", ""),
        "vertex_location": os.getenv("VERTEX_LOCATION", "us-central1"),
    }
    
    # Logging
    LOG_LEVEL: str = os.getenv('LOG_LEVEL', 'INFO')
    
    # ABI Configuration
    ABI_ROLE: str = os.getenv('ABI_ROLE', '{{ agent_display_name }}')
    ABI_NODE: str = os.getenv('ABI_NODE', 'ABI Node')
    
    # Semantic Layer
    SEMANTIC_LAYER_HOST: str = os.getenv('SEMANTIC_LAYER_HOST', 'http://{{ project_dir }}-semantic-layer:10100')
    MCP_HOST: str = os.getenv('MCP_HOST', '{{ project_dir }}-semantic-layer')
    MCP_PORT: int = int(os.getenv('MCP_PORT', '10100'))
    MCP_TRANSPORT: str = os.getenv('MCP_TRANSPORT', 'streamable-http')
    
    # Agent Card
    AGENT_CARD: str = os.getenv('AGENT_CARD', './agent_cards/{{ agent_name }}_agent.json')
    
    # A2A Validation
    A2A_VALIDATION_MODE: str = os.getenv('A2A_VALIDATION_MODE', 'permissive')
    A2A_ENABLE_AUDIT_LOG: bool = os.getenv('A2A_ENABLE_AUDIT_LOG', 'true').lower() == 'true'
    GUARDIAN_URL: str = os.getenv('GUARDIAN_URL', 'http://{{ project_dir }}-guardian:11438')
    OPA_URL: str = os.getenv('OPA_URL', 'http://{{ project_dir }}-opa:8181')
    
    # Logging & Observability
    LOG_TO_ARTIFACT_STORE: bool = os.getenv('LOG_TO_ARTIFACT_STORE', 'true').lower() == 'true'
    LOG_AGENT_NAME: str = os.getenv('LOG_AGENT_NAME', '{{ agent_name }}')
    LOG_BUCKET: str = os.getenv('LOG_BUCKET', 'abi-logs')
    
    # Artifact Store (MinIO/S3)
    ARTIFACT_ENDPOINT: str = os.getenv('ARTIFACT_ENDPOINT', 'http://{{ project_dir }}-minio:9000')
    ARTIFACT_ACCESS_KEY: str = os.getenv('ARTIFACT_ACCESS_KEY', 'minioadmin')
    ARTIFACT_SECRET_KEY: str = os.getenv('ARTIFACT_SECRET_KEY', 'minioadmin')
    ARTIFACT_BUCKET: str = os.getenv('ARTIFACT_BUCKET', 'abi-artifacts')
    
    # Ephemeral Agent Control (orchestrator only)
    EPHEMERAL_AUTO_DESTROY: bool = os.getenv('EPHEMERAL_AUTO_DESTROY', 'true').lower() == 'true'

    # Session Management (framework-managed, LB/multi-pod safe)
    # SESSION_BACKEND: "memory" (per-pod, dev) | "redis" (shared, multi-pod).
    # The framework reads these directly via abi_core.session; exposed here for
    # visibility. Use redis behind a load balancer so sessions survive pod hops.
    SESSION_BACKEND: str = os.getenv('SESSION_BACKEND', 'memory')
    SESSION_TTL: int = int(os.getenv('SESSION_TTL', '3600'))
    SESSION_REDIS_URL: str = os.getenv('SESSION_REDIS_URL', os.getenv('REDIS_URL', ''))
    ABI_SESSION_REQUIRED: bool = os.getenv('ABI_SESSION_REQUIRED', 'false').lower() == 'true'

    # Ollama Configuration (for distributed mode)
    START_OLLAMA: bool = os.getenv('START_OLLAMA', 'false').lower() == 'true'
    LOAD_MODELS: bool = os.getenv('LOAD_MODELS', 'false').lower() == 'true'
    
    # Service Module
    SERVICE_MODULE: str = os.getenv('SERVICE_MODULE', 'main')
    
    @classmethod
    def get_ollama_url(cls) -> str:
        """Get the complete Ollama URL"""
        return cls.OLLAMA_HOST
    
    @classmethod
    def get_semantic_layer_url(cls) -> str:
        """Get the complete Semantic Layer URL"""
        return cls.SEMANTIC_LAYER_HOST
    
    @classmethod
    def is_distributed_mode(cls) -> bool:
        """Check if running in distributed Ollama mode"""
        return cls.START_OLLAMA
    
    @classmethod
    def display_config(cls) -> dict:
        """Return configuration as dictionary for display"""
        return {
            'agent_name': cls.AGENT_NAME,
            'agent_display_name': cls.AGENT_DISPLAY_NAME,
            'agent_port': cls.AGENT_PORT,
            'model_name': cls.MODEL_NAME,
            'ollama_host': cls.OLLAMA_HOST,
            'semantic_layer_host': cls.SEMANTIC_LAYER_HOST,
            'log_level': cls.LOG_LEVEL,
            'distributed_mode': cls.is_distributed_mode()
        }


# Create a singleton instance
config = AgentConfig()


# Load agent card at module import time
def _load_agent_card() -> AgentCard:
    """Load and validate the agent card from file."""
    card, _meta = load_agent_card(config.AGENT_CARD)

    if card.name != config.AGENT_DISPLAY_NAME:
        raise ValueError(
            f"Agent card name mismatch. "
            f"Expected: {config.AGENT_DISPLAY_NAME}, "
            f"Got: {card.name}"
        )

    return card


# Agent card loaded at import time - ready to use
AGENT_CARD = _load_agent_card()
