"""
Simple Langfuse Client Wrapper
Minimal setup using langfuse.langchain module
With propagate_attributes for proper user_id tracking
"""

import asyncio
import logging
from concurrent.futures import ThreadPoolExecutor

from langfuse import Langfuse, get_client
from langfuse.langchain import CallbackHandler

from config import (
    LANGFUSE_PUBLIC_KEY,
    LANGFUSE_SECRET_KEY,
)

logger = logging.getLogger(__name__)

__all__ = ["async_flush_langfuse", "get_callback_handler", "get_langfuse_client"]


class LangfuseClientManager:
    """
    Singleton manager for Langfuse client.
    Lazy loading - only initialize when first needed.
    """

    def __init__(self):
        self._client: Langfuse | None = None
        self._executor: ThreadPoolExecutor | None = None
        self._initialized = False

    def get_client(self) -> Langfuse | None:
        """
        Lazy loading - initialize Langfuse client on first call.
        """
        if self._initialized:
            return self._client

        logger.info("🔧 [LAZY LOADING] Initializing Langfuse client (first time)")

        if not LANGFUSE_PUBLIC_KEY or not LANGFUSE_SECRET_KEY:
            logger.warning("⚠️ LANGFUSE KEYS MISSING. Tracing disabled.")
            self._initialized = True
            return None

        try:
            self._client = get_client()
            self._executor = ThreadPoolExecutor(max_workers=1, thread_name_prefix="langfuse_export")

            if self._client.auth_check():
                logger.info("✅ Langfuse Ready! (async batch export)")
                self._initialized = True
                return self._client

            logger.error("❌ Langfuse auth failed")
            self._initialized = True
            return None

        except Exception as e:
            logger.error(f"❌ Langfuse init error: {e}")
            self._initialized = True
            return None

    async def async_flush(self):
        """
        Async wrapper to flush Langfuse without blocking event loop.
        Uses thread pool executor to run sync flush in background.
        """
        client = self.get_client()
        if not client or not self._executor:
            return

        try:
            loop = asyncio.get_event_loop()
            await loop.run_in_executor(self._executor, client.flush)
            logger.debug("📤 Langfuse flushed (async)")
        except Exception as e:
            logger.warning(f"⚠️ Async flush failed: {e}")

    def get_callback_handler(self, **kwargs) -> CallbackHandler | None:
        """Get CallbackHandler instance."""
        client = self.get_client()
        if not client:
            logger.warning("⚠️ Langfuse client not available")
            return None

        try:
            handler = CallbackHandler(**kwargs)
            logger.debug("✅ Langfuse CallbackHandler created")
            return handler
        except Exception as e:
            logger.warning(f"⚠️ CallbackHandler error: {e}")
            return None


# --- Singleton ---
_manager = LangfuseClientManager()
get_langfuse_client = _manager.get_client
async_flush_langfuse = _manager.async_flush


def get_callback_handler(**kwargs) -> CallbackHandler | None:
    """Get CallbackHandler instance (wrapper for manager)."""
    return _manager.get_callback_handler(**kwargs)
