"""
LLM Handler for Warden Bridge.
Handles AI-driven code analysis and streaming responses.
"""

from collections.abc import AsyncIterator
from typing import Any

from warden.cli_bridge.handlers.base import BaseHandler
from warden.cli_bridge.protocol import ErrorCode, IPCError
from warden.shared.infrastructure.logging import get_logger

logger = get_logger(__name__)


class LLMHandler(BaseHandler):
    """Handles LLM-powered analysis and chat streaming."""

    def __init__(self, llm_config: Any, llm_service: Any | None = None):
        self.llm_config = llm_config
        self.llm_service = llm_service

    async def analyze_with_llm_async(
        self, prompt: str, provider: str | None = None, stream: bool = True
    ) -> AsyncIterator[str]:
        """Execute LLM analysis with streaming or full completion."""
        from warden.llm.factory import create_client
        from warden.llm.types import LlmProvider

        try:
            # Resolve provider
            resolved_provider = self.llm_config.default_provider
            if provider:
                try:
                    resolved_provider = LlmProvider(provider)
                except ValueError:
                    raise IPCError(ErrorCode.INVALID_PARAMS, f"Invalid provider: {provider}")

            # Get client
            if self.llm_service and (not provider or self.llm_service.provider == resolved_provider):
                llm_client = self.llm_service
            else:
                llm_client = create_client(resolved_provider)

            if not llm_client:
                raise IPCError(ErrorCode.LLM_ERROR, "No LLM provider available")

            if stream:
                async for chunk in llm_client.stream_completion_async(prompt):
                    yield chunk
            else:
                response = await llm_client.complete_async(prompt)
                yield response.content

        except IPCError:
            raise
        except Exception as e:
            logger.error("llm_analysis_failed", error=str(e), provider=provider)
            raise IPCError(ErrorCode.LLM_ERROR, f"LLM analysis failed: {e}")
