"""
Genesis Elestio Infrastructure Configuration

Central configuration for all Elestio cloud services.
Import this module to get connection details for PostgreSQL, Qdrant, and Redis.

Usage:
    from elestio_config import PostgresConfig, QdrantConfig, RedisConfig

    # PostgreSQL
    conn = psycopg2.connect(PostgresConfig.connection_string)

    # Qdrant
    client = QdrantClient(url=QdrantConfig.url, api_key=QdrantConfig.api_key)

    # Redis
    r = redis.from_url(RedisConfig.connection_string)
"""

import os
from dataclasses import dataclass


@dataclass
class PostgresConfig:
    """PostgreSQL (Episodic Memory) configuration."""
    host: str = "postgresql-genesis-u50607.vm.elestio.app"
    port: int = 25432
    user: str = "postgres"
    password: str = "CiBjh6LM7Yuqkq-jo2r7eQDw"
    database: str = "postgres"

    @property
    def connection_string(self) -> str:
        return f"postgresql://{self.user}:{self.password}@{self.host}:{self.port}/{self.database}"

    @classmethod
    def get_connection_params(cls) -> dict:
        """Get connection parameters for psycopg2."""
        config = cls()
        return {
            "host": config.host,
            "port": config.port,
            "user": config.user,
            "password": config.password,
            "database": config.database
        }


@dataclass
class QdrantConfig:
    """Qdrant (Vector Memory) configuration."""
    host: str = "qdrant-b3knu-u50607.vm.elestio.app"
    port: int = 6333
    api_key: str = "7b74e6621bd0e6650789f6662bca4cbf4143d3d1d710a0002b3b563973ca6876"
    collection_name: str = "genesis_vectors"
    vector_size: int = 1536
    distance: str = "Cosine"

    @property
    def url(self) -> str:
        return f"https://{self.host}:{self.port}"

    @classmethod
    def get_client_params(cls) -> dict:
        """Get parameters for QdrantClient."""
        config = cls()
        return {
            "url": config.url,
            "api_key": config.api_key
        }


@dataclass
class RedisConfig:
    """Redis (Working Memory) configuration."""
    host: str = "redis-genesis-u50607.vm.elestio.app"
    port: int = 26379
    user: str = "default"
    password: str = "e2ZyYYr4oWRdASI2CaLc-"

    @property
    def connection_string(self) -> str:
        return f"redis://{self.user}:{self.password}@{self.host}:{self.port}"

    @classmethod
    def get_connection_params(cls) -> dict:
        """Get connection parameters for redis-py."""
        config = cls()
        return {
            "host": config.host,
            "port": config.port,
            "username": config.user,
            "password": config.password,
            "decode_responses": True
        }

    @classmethod
    def get_client_params(cls) -> dict:
        """Alias for get_connection_params (backward compatibility)."""
        return cls.get_connection_params()


@dataclass
class N8NConfig:
    """n8n (Workflow Orchestration) configuration."""
    host: str = "n8n-genesis-u50607.vm.elestio.app"
    port: int = 443
    api_key: str = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxZTA3Y2UwYi1lZmZmLTRlODItOGRkZS02ODA3OGZiNjU4MDQiLCJpc3MiOiJuOG4iLCJhdWQiOiJwdWJsaWMtYXBpIiwiaWF0IjoxNzY2Nzc2MDAyfQ.viRWPPX8t6cTqXEtBEw7pj-0ar_Nvjrh0_8T1LGLi6o"

    @property
    def api_url(self) -> str:
        return f"https://{self.host}/api/v1"

    @property
    def headers(self) -> dict:
        return {"X-N8N-API-KEY": self.api_key}


# Environment variable overrides (for Modal/cloud deployment)
def get_postgres_config() -> PostgresConfig:
    """Get PostgreSQL config with env var overrides."""
    return PostgresConfig(
        host=os.environ.get("GENESIS_POSTGRES_HOST", PostgresConfig.host),
        port=int(os.environ.get("GENESIS_POSTGRES_PORT", PostgresConfig.port)),
        user=os.environ.get("GENESIS_POSTGRES_USER", PostgresConfig.user),
        password=os.environ.get("GENESIS_POSTGRES_PASSWORD", PostgresConfig.password),
        database=os.environ.get("GENESIS_POSTGRES_DATABASE", PostgresConfig.database)
    )


def get_qdrant_config() -> QdrantConfig:
    """Get Qdrant config with env var overrides."""
    return QdrantConfig(
        host=os.environ.get("GENESIS_QDRANT_HOST", QdrantConfig.host),
        port=int(os.environ.get("GENESIS_QDRANT_PORT", QdrantConfig.port)),
        api_key=os.environ.get("GENESIS_QDRANT_API_KEY", QdrantConfig.api_key)
    )


def get_redis_config() -> RedisConfig:
    """Get Redis config with env var overrides."""
    return RedisConfig(
        host=os.environ.get("GENESIS_REDIS_HOST", RedisConfig.host),
        port=int(os.environ.get("GENESIS_REDIS_PORT", RedisConfig.port)),
        user=os.environ.get("GENESIS_REDIS_USER", RedisConfig.user),
        password=os.environ.get("GENESIS_REDIS_PASSWORD", RedisConfig.password)
    )


def get_n8n_config() -> N8NConfig:
    """Get n8n config with env var overrides."""
    return N8NConfig(
        host=os.environ.get("GENESIS_N8N_HOST", N8NConfig.host),
        api_key=os.environ.get("GENESIS_N8N_API_KEY", N8NConfig.api_key)
    )


@dataclass
class BrowserlessConfig:
    """
    Browserless (Cloud Browser Army) — LIVE on Elestio DO Sydney ✅
    Service: browserless-genesis (MICRO-1C-1G, running, created 1 day ago)
    Provider: Digital Ocean, Australia/Sydney — optimal for AU client QA.

    Provides cloud-hosted Chromium via WebSocket/REST (Playwright-compatible).
    Enables 10-50 parallel browser sessions without local resource consumption.
    Used by: scripts/browserless_qa_army.py, all browser automation agents.

    Get TOKEN from: Elestio dashboard → browserless-genesis → Env Vars → TOKEN
    """
    host: str = os.environ.get("BROWSERLESS_HOST", "browserless-genesis-u50607.vm.elestio.app")
    port: int = 3000
    token: str = os.environ.get("BROWSERLESS_TOKEN", "")
    # MICRO-1C-1G → 10-15 safe concurrent | MEDIUM-2C-4G → 50 concurrent
    max_concurrent: int = int(os.environ.get("BROWSERLESS_MAX_SESSIONS", "10"))

    @property
    def ws_url(self) -> str:
        """WebSocket URL for playwright.chromium.connect_over_cdp()."""
        base = f"wss://{self.host}:{self.port}"
        return f"{base}?token={self.token}" if self.token else base

    @property
    def http_url(self) -> str:
        """HTTP base URL for REST API (screenshots, PDF, scraping)."""
        return f"https://{self.host}:{self.port}"

    @property
    def health_url(self) -> str:
        url = f"{self.http_url}/pressure"
        return f"{url}?token={self.token}" if self.token else url

    @classmethod
    def get_playwright_connect_url(cls) -> str:
        """
        Use this with playwright.chromium.connect_over_cdp():

            from elestio_config import BrowserlessConfig
            config = BrowserlessConfig()
            browser = await p.chromium.connect_over_cdp(config.get_playwright_connect_url())
        """
        return cls().ws_url


@dataclass
class FalkorDBConfig:
    """
    FalkorDB (Episodic Graph Memory) — TO BE PROVISIONED on Elestio.
    Purpose: AIVA's graph memory — who did what, when, why, how it connects.
    Provision: Elestio → New Service → FalkorDB → MEDIUM-2C-4G → Netcup US
    falkordb-py: pip install falkordb
    """
    host: str = os.environ.get("FALKORDB_HOST", "falkordb-genesis-u50607.vm.elestio.app")
    port: int = int(os.environ.get("FALKORDB_PORT", "6379"))
    password: str = os.environ.get("FALKORDB_PASSWORD", "")
    graph_name: str = "genesis_episodic"

    @classmethod
    def get_client_params(cls) -> dict:
        """
        Use with falkordb-py:
            import falkordb
            db = falkordb.FalkorDB(**FalkorDBConfig.get_client_params())
            graph = db.select_graph(FalkorDBConfig.graph_name)
        """
        config = cls()
        return {"host": config.host, "port": config.port, "password": config.password}


@dataclass
class GraphitiConfig:
    """
    Graphiti (Temporal Knowledge Graph) — TO BE PROVISIONED on Elestio.
    Built by Zep. Sits on FalkorDB. Time-aware edges: 'What changed since X?'
    Provision: Elestio → New Service → Custom Docker → zep-ai/graphiti → Netcup US
    Docs: https://help.getzep.com/graphiti
    """
    host: str = os.environ.get("GRAPHITI_HOST", "graphiti-genesis-u50607.vm.elestio.app")
    port: int = int(os.environ.get("GRAPHITI_PORT", "8000"))
    api_key: str = os.environ.get("GRAPHITI_API_KEY", "")

    @property
    def api_url(self) -> str:
        return f"https://{self.host}:{self.port}"

    @property
    def headers(self) -> dict:
        return {"Authorization": f"Bearer {self.api_key}"} if self.api_key else {}


def get_browserless_config() -> BrowserlessConfig:
    """Get Browserless config. Set BROWSERLESS_TOKEN from Elestio dashboard."""
    return BrowserlessConfig()


def get_falkordb_config() -> FalkorDBConfig:
    """Get FalkorDB config. Provision service first on Elestio."""
    return FalkorDBConfig()


def get_graphiti_config() -> GraphitiConfig:
    """Get Graphiti config. Provision after FalkorDB."""
    return GraphitiConfig()


# Quick test function
def test_connections():
    """Test all Elestio service connections."""
    results = {}

    # Test PostgreSQL
    try:
        import psycopg2
        config = get_postgres_config()
        conn = psycopg2.connect(**PostgresConfig.get_connection_params())
        cursor = conn.cursor()
        cursor.execute("SELECT 1")
        conn.close()
        results["postgresql"] = "✅ Connected"
    except Exception as e:
        results["postgresql"] = f"❌ {e}"

    # Test Qdrant
    try:
        import requests
        config = get_qdrant_config()
        resp = requests.get(
            f"{config.url}/collections",
            headers={"api-key": config.api_key},
            timeout=10
        )
        if resp.status_code == 200:
            results["qdrant"] = "✅ Connected"
        else:
            results["qdrant"] = f"❌ Status {resp.status_code}"
    except Exception as e:
        results["qdrant"] = f"❌ {e}"

    # Test Redis
    try:
        import redis
        config = get_redis_config()
        r = redis.Redis(**RedisConfig.get_connection_params())
        r.ping()
        results["redis"] = "✅ Connected"
    except Exception as e:
        results["redis"] = f"❌ {e}"

    return results


if __name__ == "__main__":
    print("Genesis Elestio Configuration")
    print("=" * 40)
    print(f"PostgreSQL: {PostgresConfig().host}:{PostgresConfig().port}")
    print(f"Qdrant:     {QdrantConfig().url}")
    print(f"Redis:      {RedisConfig().host}:{RedisConfig().port}")
    print(f"n8n:        {N8NConfig().api_url}")
    print()
    print("Testing connections...")
    results = test_connections()
    for service, status in results.items():
        print(f"  {service}: {status}")
