"""Command for regenerating the last AI response."""

from dataclasses import dataclass
from uuid import UUID

from alloy_runtime_sdk.api_client.client import ApiClient
from alloy_runtime_types.dtos.generation import (
    AgentSource,
    DirectModelSource,
    GenerateTextRequest,
)
from alloy_runtime_types.enums.provider import Provider
from alloy_runtime_sdk.logging.config import get_logger

from cli.tui.chat.commands.base import CommandResult
from cli.tui.chat.store import ChatStore

logger = get_logger(__name__)


@dataclass
class RegenerateCommand:
    """Command to regenerate the last AI response.

    Supports two modes:
    - Agent mode: Uses agent_id to determine model and system instruction
    - Model mode: Uses provider_key/provider_model_name/system_instruction directly

    This command:
    1. Transitions store to SENDING phase
    2. Sends a regenerate request to the API
    3. Waits for the final non-streaming response
    4. Leaves the store in SENDING on success so the caller can reload persisted
       messages before clearing the waiting state

    Attributes:
        client: Server client for API calls.
        store: Chat store for state management.
        session_id: ID of the current chat session.
        agent_id: ID of the agent to use for regeneration (agent mode).
        provider_key: Provider key (model mode).
        provider_model_name: Model name (model mode).
        system_instruction: System instruction (model mode).
    """

    client: ApiClient
    store: ChatStore
    session_id: UUID
    # Agent mode
    agent_id: UUID | None = None
    # Model mode
    provider_key: str | None = None
    provider_model_name: str | None = None
    system_instruction: str | None = None

    async def execute(self) -> CommandResult[None]:
        """Execute the regenerate response operation.

        Returns:
            CommandResult indicating success or failure.
        """
        logger.info("regenerate_starting", session_id=str(self.session_id))
        self.store.start_generation()

        try:
            # Build model source based on mode
            if self.agent_id is not None:
                model_source = AgentSource(agent=self.agent_id)
            elif self.provider_key and self.provider_model_name:
                model_source = DirectModelSource(
                    provider_key=Provider(self.provider_key),
                    provider_model_name=self.provider_model_name,
                )
            else:
                self.store.finish_generation()
                return CommandResult[None](
                    success=False,
                    error="No agent or model configured for this session",
                )

            request = GenerateTextRequest(
                model_source=model_source,
                chat_session_id=self.session_id,
                regenerate=True,
                stream=False,
                tags=[],
                # Only include system instruction for model mode
                system_instruction=self.system_instruction
                if self.agent_id is None
                else None,
            )

            await self.client.generate_text(request)

            logger.info("regenerate_completed")
            return CommandResult[None](success=True, data=None)

        except Exception as e:
            logger.warning("regenerate_failed", error=str(e))
            self.store.finish_generation()
            return CommandResult[None](success=False, error=str(e))
