import datetime
import json
import typing

import prisma.models
import pydantic

import backend.data.block
import backend.data.graph
import backend.server.model


class LibraryAgent(pydantic.BaseModel):
    id: str  # Changed from agent_id to match GraphMeta

    agent_id: str
    agent_version: int  # Changed from agent_version to match GraphMeta

    preset_id: str | None

    updated_at: datetime.datetime

    name: str
    description: str

    # Made input_schema and output_schema match GraphMeta's type
    input_schema: dict[str, typing.Any]  # Should be BlockIOObjectSubSchema in frontend
    output_schema: dict[str, typing.Any]  # Should be BlockIOObjectSubSchema in frontend

    is_favorite: bool
    is_created_by_user: bool

    is_latest_version: bool

    @staticmethod
    def from_db(agent: prisma.models.LibraryAgent):
        if not agent.Agent:
            raise ValueError("AgentGraph is required")

        graph = backend.data.graph.GraphModel.from_db(agent.Agent)

        agent_updated_at = agent.Agent.updatedAt
        lib_agent_updated_at = agent.updatedAt

        # Take the latest updated_at timestamp either when the graph was updated or the library agent was updated
        updated_at = (
            max(agent_updated_at, lib_agent_updated_at)
            if agent_updated_at
            else lib_agent_updated_at
        )

        return LibraryAgent(
            id=agent.id,
            agent_id=agent.agentId,
            agent_version=agent.agentVersion,
            updated_at=updated_at,
            name=graph.name,
            description=graph.description,
            input_schema=graph.input_schema,
            output_schema=graph.output_schema,
            is_favorite=agent.isFavorite,
            is_created_by_user=agent.isCreatedByUser,
            is_latest_version=graph.is_active,
            preset_id=agent.AgentPreset.id if agent.AgentPreset else None,
        )


class LibraryAgentPreset(pydantic.BaseModel):
    id: str
    updated_at: datetime.datetime

    agent_id: str
    agent_version: int

    name: str
    description: str

    is_active: bool
    inputs: dict[str, typing.Union[backend.data.block.BlockInput, typing.Any]]

    @staticmethod
    def from_db(preset: prisma.models.AgentPreset):
        input_data = {}

        for data in preset.InputPresets or []:
            input_data[data.name] = json.loads(data.data)

        return LibraryAgentPreset(
            id=preset.id,
            updated_at=preset.updatedAt,
            agent_id=preset.agentId,
            agent_version=preset.agentVersion,
            name=preset.name,
            description=preset.description,
            is_active=preset.isActive,
            inputs=input_data,
        )


class LibraryAgentPresetResponse(pydantic.BaseModel):
    presets: list[LibraryAgentPreset]
    pagination: backend.server.model.Pagination


class CreateLibraryAgentPresetRequest(pydantic.BaseModel):
    name: str
    description: str
    inputs: dict[str, typing.Union[backend.data.block.BlockInput, typing.Any]]
    agent_id: str
    agent_version: int
    is_active: bool

import typing

import pydantic


class LibraryAgent(pydantic.BaseModel):
    id: str  # Changed from agent_id to match GraphMeta
    version: int  # Changed from agent_version to match GraphMeta
    is_active: bool  # Added to match GraphMeta
    name: str
    description: str

    isCreatedByUser: bool
    # Made input_schema and output_schema match GraphMeta's type
    input_schema: dict[str, typing.Any]  # Should be BlockIOObjectSubSchema in frontend
    output_schema: dict[str, typing.Any]  # Should be BlockIOObjectSubSchema in frontend
