from __future__ import annotations
from types import SimpleNamespace

from backend.agents.tools_using_v2 import LLMTool
from backend.constants import READ_ARTIFACT_TOOL_NAME, READ_ARTIFACT_TOOL_REF
from backend.services.artifact_read_service.service import resolve_artifact_read_for_llm_payload
from pydantic import BaseModel, Field

READ_ARTIFACT_DISPLAY_NAME = "Read Artifact"


class ReadArtifactSpec(BaseModel):
    message_id: str = Field(..., description="Assistant message id that originally produced the artifact.")
    artifacts_id: str = Field(
        ...,
        description="Artifacts group id from a prior assistant artifact reference in the conversation context.",
    )
    artifact_index: int = Field(
        ...,
        ge=0,
        description="Zero-based index of the artifact inside that artifacts group. This is not a parts index.",
    )


class ReadArtifactTool:
    def __init__(self, app):
        self._app = app

    project_key = "AgentHub"
    tool_id = READ_ARTIFACT_TOOL_NAME
    tool_name = READ_ARTIFACT_TOOL_NAME

    def get_settings(self):
        return SimpleNamespace(_settings={"type": "builtin"})

    def describe_tool_call(self, input, llm_descriptor, context=None, subtool_name=None):
        try:
            spec = ReadArtifactSpec.model_validate(input or {})
        except Exception:
            return "Read an artifact."
        return f"Read artifact {spec.artifacts_id}[{spec.artifact_index}]."

    def run(
        self,
        input,
        context=None,
        subtool_name=None,
        memory_fragment=None,
        tool_validation_responses=None,
        tool_validation_requests=None,
    ):
        spec = ReadArtifactSpec.model_validate(input or {})
        resolved = resolve_artifact_read_for_llm_payload(
            message_id=spec.message_id,
            artifacts_id=spec.artifacts_id,
            artifact_index=spec.artifact_index,
            context=context,
            app=self._app,
        )
        read_result = resolved.read_result
        return {
            "output": {"result": read_result.result},
            "parts": read_result.parts,
            "sources": [],
            "artifacts": [],
            "trace": None,
            "toolValidationRequests": None,
            "memoryFragment": None,
        }


def build_read_artifact_llm_tool(app) -> LLMTool:
    return LLMTool(
        llm_tool_name=READ_ARTIFACT_TOOL_NAME,
        llm_descriptor={
            "type": "function",
            "function": {
                "name": READ_ARTIFACT_TOOL_NAME,
                "description": (
                    "Read a previously generated artifact in more detail using an explicit artifact reference already "
                    "present in the conversation context. Use it when you need the content of a PPTX deck YAML, a "
                    "records artifact, a markdown artifact, a PDF artifact, a DOCX artifact, or an inline image "
                    "artifact. Generated document History markers have no readable content. "
                    "artifact_index refers to the artifact position inside the artifacts group, not to a part inside "
                    "the artifact."
                ),
                "parameters": ReadArtifactSpec.model_json_schema(),
            },
        },
        dku_tool=ReadArtifactTool(app),
        dku_tool_ref=READ_ARTIFACT_TOOL_REF,
        dku_tool_type="builtin",
        dku_tool_name=READ_ARTIFACT_DISPLAY_NAME,
        dku_subtool_name=None,
        require_validation=False,
        allow_editing_inputs=False,
    )
