from __future__ import annotations

from typing import Any

from pydantic import BaseModel

from skyvern.forge.sdk.settings_manager import SettingsManager
from skyvern.webeye.actions.actions import Action, ActionTypeUnion
from skyvern.webeye.actions.responses import ActionResult
from skyvern.webeye.scraper.scraper import ScrapedPage


class AgentStepOutput(BaseModel):
    """
    Output of the agent step, this is recorded in the database.
    """

    # Will be deprecated once we move to the new format below
    action_results: list[ActionResult] | None = None
    # Nullable for backwards compatibility, once backfill is done, this won't be nullable anymore
    actions_and_results: list[tuple[ActionTypeUnion, list[ActionResult]]] | None = None

    def __repr__(self) -> str:
        return f"AgentStepOutput({self.model_dump()})"

    def __str__(self) -> str:
        return self.__repr__()


class DetailedAgentStepOutput(BaseModel):
    """
    Output of the agent step, this is not recorded in the database, only used for debugging in the Jupyter notebook.
    """

    scraped_page: ScrapedPage | None
    extract_action_prompt: str | None
    llm_response: dict[str, Any] | None
    actions: list[Action] | None
    action_results: list[ActionResult] | None
    actions_and_results: list[tuple[ActionTypeUnion, list[ActionResult]]] | None

    class Config:
        exclude = ["scraped_page", "extract_action_prompt"]

    def __repr__(self) -> str:
        if SettingsManager.get_settings().DEBUG_MODE:
            return f"DetailedAgentStepOutput({self.model_dump()})"
        else:
            return f"AgentStepOutput({self.to_agent_step_output().model_dump()})"

    def __str__(self) -> str:
        return self.__repr__()

    def to_agent_step_output(self) -> AgentStepOutput:
        return AgentStepOutput(
            action_results=self.action_results if self.action_results else [],
            actions_and_results=self.actions_and_results if self.actions_and_results else [],
        )
