"""
Mock LangChain-compatible chat model for development mode

Wraps MockAIProvider to work with LangChain's agent framework.
"""

from typing import Any, List, Optional, Dict
from langchain_core.language_models import BaseChatModel
from langchain_core.messages import AIMessage, BaseMessage
from langchain_core.outputs import ChatResult, ChatGeneration
from .mock_ai_provider import MockAIProvider


class MockChatModel(BaseChatModel):
    """
    Mock chat model compatible with LangChain's agent framework

    Attributes:
        date: Current trading date for response generation
        step_counter: Tracks reasoning steps within a trading session
        provider: MockAIProvider instance
    """

    date: str = "2025-01-01"
    step_counter: int = 0
    provider: Optional[MockAIProvider] = None

    def __init__(self, date: str = "2025-01-01", **kwargs):
        """
        Initialize mock chat model

        Args:
            date: Trading date for mock responses
            **kwargs: Additional LangChain model parameters
        """
        super().__init__(**kwargs)
        self.date = date
        self.step_counter = 0
        self.provider = MockAIProvider()

    @property
    def _llm_type(self) -> str:
        """Return identifier for this LLM type"""
        return "mock-chat-model"

    def _generate(
        self,
        messages: List[BaseMessage],
        stop: Optional[List[str]] = None,
        run_manager: Optional[Any] = None,
        **kwargs: Any,
    ) -> ChatResult:
        """
        Generate mock response (synchronous)

        Args:
            messages: Input messages (ignored in mock)
            stop: Stop sequences (ignored in mock)
            run_manager: LangChain run manager
            **kwargs: Additional generation parameters

        Returns:
            ChatResult with mock AI response
        """
        # Parameters are required by BaseChatModel interface but unused in mock
        _ = messages, stop, run_manager, kwargs
        response_text = self.provider.generate_response(self.date, self.step_counter)
        self.step_counter += 1

        message = AIMessage(
            content=response_text,
            response_metadata={"finish_reason": "stop"}
        )

        generation = ChatGeneration(message=message)
        return ChatResult(generations=[generation])

    async def _agenerate(
        self,
        messages: List[BaseMessage],
        stop: Optional[List[str]] = None,
        run_manager: Optional[Any] = None,
        **kwargs: Any,
    ) -> ChatResult:
        """
        Generate mock response (asynchronous)

        Same as _generate but async-compatible for LangChain agents.
        """
        return self._generate(messages, stop, run_manager, **kwargs)

    def invoke(self, input: Any, **kwargs) -> AIMessage:
        """Synchronous invoke (LangChain compatibility)"""
        if isinstance(input, list):
            messages = input
        else:
            messages = []

        result = self._generate(messages, **kwargs)
        return result.generations[0].message

    async def ainvoke(self, input: Any, **kwargs) -> AIMessage:
        """Asynchronous invoke (LangChain compatibility)"""
        if isinstance(input, list):
            messages = input
        else:
            messages = []

        result = await self._agenerate(messages, **kwargs)
        return result.generations[0].message
