from typing import Dict, List, Literal, Optional, TypedDict

from typing_extensions import NotRequired


class TextCompletionModel(TypedDict):
    id: str
    name: str


class EnterpriseAgentItem(TypedDict):
    id: str
    projectKey: NotRequired[Optional[str]]
    type: NotRequired[Optional[str]]
    name: str
    sourceAgentName: NotRequired[Optional[str]]
    description: NotRequired[Optional[str]]
    exampleQuestions: NotRequired[Optional[List[str]]]
    additionalInstructions: NotRequired[Optional[str]]
    allowInsightsCreation: NotRequired[Optional[bool]]
    storiesWorkspace: NotRequired[Optional[str]]


class ConversationStarterExample(TypedDict):
    id: str
    label: str
    query: str
    enterpriseAgents: List[str]


class PromptAttributes(TypedDict, total=False):
    enabled: bool


class AdminConfig(TypedDict):
    version: NotRequired[Optional[str]]

    required: NotRequired[Optional[List[str]]]

    agentHubLLM: NotRequired[Optional[str]]
    agentHubOptionalInstructions: NotRequired[Optional[str]]
    orchestrationMode: NotRequired[Optional[Literal["tools", "manual"]]]

    smartMode: NotRequired[Optional[bool]]
    permanentlyDeleteMessages: NotRequired[Optional[bool]]
    allowDisableAgents: NotRequired[Optional[bool]]
    logsLevel: NotRequired[Optional[Literal["info", "debug"]]]
    conversationStarterExamples: NotRequired[Optional[List[ConversationStarterExample]]]

    enableDocumentUpload: NotRequired[Optional[bool]]
    extractionMode: NotRequired[Optional[Literal["pagesScreenshots", "pagesText"]]]
    textExtractionType: NotRequired[Optional[Literal["IGNORE", "OCR", "VLM_ANNOTATE"]]]
    maxImagesInConversation: NotRequired[Optional[int]]
    uploadManagedFolder: NotRequired[Optional[str]]
    conversationVisionLLM: NotRequired[Optional[str]]

    myAgentsEnabled: NotRequired[Optional[bool]]
    myAgentsTextCompletionModels: NotRequired[Optional[List[TextCompletionModel]]]
    myAgentsEmbeddingModel: NotRequired[Optional[str]]
    myAgentsFsConnection: NotRequired[Optional[str]]
    myAgentsFolder: NotRequired[Optional[str]]
    myAgentsNumDocs: NotRequired[Optional[int]]
    myAgentsManagedTools: NotRequired[Optional[List[str]]]
    myAgentsEnablePromptLibrary: NotRequired[Optional[bool]]

    enterpriseAgents: NotRequired[Optional[List[EnterpriseAgentItem]]]

    chartsGenerationMode: NotRequired[Optional[Literal["auto", "manual", "disabled"]]]
    chartsTextCompletionModel: NotRequired[Optional[str]]
    chartsMaxArtifactsSize: NotRequired[Optional[int]]

    promptsAttributesById: NotRequired[Optional[Dict[str, PromptAttributes]]]

    myAgentsEnableGroupsRestriction: NotRequired[Optional[bool]]
    myAgentsExcludedShareGroups: NotRequired[Optional[List[str]]]


class Prompt(TypedDict):
    id: str
    name: str
    description: str
    prompt: str
    category: str
    tags: List[str]
    isDefault: bool
    createdAt: str
    updatedAt: str


class PromptsLibrary(TypedDict):
    version: str
    prompts: List[Prompt]


def is_field_required(config: Optional[AdminConfig], field_name: str) -> bool:
    if not config:
        return False
    required = config.get("required")
    return field_name in required if required else False


def get_required_fields(config: Optional[AdminConfig]) -> List[str]:
    if not config:
        return []
    return config.get("required") or []


def set_field_required(config: AdminConfig, field_name: str, required: bool) -> None:
    if "required" not in config or config["required"] is None:
        config["required"] = []

    req_list = config["required"]

    if required and field_name not in req_list:
        req_list.append(field_name)
    elif not required and field_name in req_list:
        req_list.remove(field_name)


def add_required_fields(config: AdminConfig, field_names: List[str]) -> None:
    if "required" not in config or config["required"] is None:
        config["required"] = []

    for field_name in field_names:
        if field_name not in config["required"]:
            config["required"].append(field_name)


def remove_required_fields(config: AdminConfig, field_names: List[str]) -> None:
    if "required" not in config or config["required"] is None:
        return

    config["required"] = [f for f in config["required"] if f not in field_names]
