from __future__ import annotations

from collections.abc import Mapping
from typing import TYPE_CHECKING, Any, TypeVar

from attrs import define as _attrs_define
from attrs import field as _attrs_field

from ..types import UNSET, Unset

if TYPE_CHECKING:
    from ..models.agents_config import AgentsConfig
    from ..models.artifact_llm_config import ArtifactLLMConfig
    from ..models.chunker_config import ChunkerConfig
    from ..models.doctag_llm_config import DoctagLLMConfig
    from ..models.embedder_config import EmbedderConfig
    from ..models.evaluator_llm_config import EvaluatorLLMConfig
    from ..models.keyword_embedder_config import KeywordEmbedderConfig
    from ..models.model_citation_config import ModelCitationConfig
    from ..models.parser_config import ParserConfig
    from ..models.query_llm_config import QueryLLMConfig
    from ..models.reranker_config import RerankerConfig
    from ..models.retriever_config import RetrieverConfig
    from ..models.summarise_llm_config import SummariseLLMConfig
    from ..models.title_llm_config import TitleLLMConfig


T = TypeVar("T", bound="AllConfigs")


@_attrs_define
class AllConfigs:
    """
    Attributes:
        agents (AgentsConfig | Unset): Configuration for agent workflow.
        query_llm (QueryLLMConfig | Unset):
        evaluator_llm (EvaluatorLLMConfig | Unset):
        title_llm (TitleLLMConfig | Unset):
        summarise_llm (SummariseLLMConfig | Unset): Configuration for conversation summarisation. Used for compaction
            and general summaries.
        doctag_llm (DoctagLLMConfig | Unset): Configuration for DoctagLLM - extracts information from documents based on
            tag instructions.
        artifact_llm (ArtifactLLMConfig | Unset): Configuration for ArtifactLLM - synthesizes document artifacts
            (skills, memories, reports).

            Produces markdown documents from gathered context (learnings, retrieval results,
            conversation history). Output is saved as a .txt document through the standard
            upload pipeline and linked to an assistant tag via DocTags.

            Note: The assistant tag relationship is stored on Configurations.tag_id (FK),
            not in this config. This config just controls synthesis behavior.
        model_citation (ModelCitationConfig | Unset):
        retriever (RetrieverConfig | Unset):
        reranker (RerankerConfig | Unset):
        parser (ParserConfig | Unset):
        chunker (ChunkerConfig | Unset):
        embedder (EmbedderConfig | Unset):
        keyword_embedder (KeywordEmbedderConfig | Unset): Configuration for keyword embedder with BM25 scoring.
    """

    agents: AgentsConfig | Unset = UNSET
    query_llm: QueryLLMConfig | Unset = UNSET
    evaluator_llm: EvaluatorLLMConfig | Unset = UNSET
    title_llm: TitleLLMConfig | Unset = UNSET
    summarise_llm: SummariseLLMConfig | Unset = UNSET
    doctag_llm: DoctagLLMConfig | Unset = UNSET
    artifact_llm: ArtifactLLMConfig | Unset = UNSET
    model_citation: ModelCitationConfig | Unset = UNSET
    retriever: RetrieverConfig | Unset = UNSET
    reranker: RerankerConfig | Unset = UNSET
    parser: ParserConfig | Unset = UNSET
    chunker: ChunkerConfig | Unset = UNSET
    embedder: EmbedderConfig | Unset = UNSET
    keyword_embedder: KeywordEmbedderConfig | Unset = UNSET
    additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)

    def to_dict(self) -> dict[str, Any]:
        agents: dict[str, Any] | Unset = UNSET
        if not isinstance(self.agents, Unset):
            agents = self.agents.to_dict()

        query_llm: dict[str, Any] | Unset = UNSET
        if not isinstance(self.query_llm, Unset):
            query_llm = self.query_llm.to_dict()

        evaluator_llm: dict[str, Any] | Unset = UNSET
        if not isinstance(self.evaluator_llm, Unset):
            evaluator_llm = self.evaluator_llm.to_dict()

        title_llm: dict[str, Any] | Unset = UNSET
        if not isinstance(self.title_llm, Unset):
            title_llm = self.title_llm.to_dict()

        summarise_llm: dict[str, Any] | Unset = UNSET
        if not isinstance(self.summarise_llm, Unset):
            summarise_llm = self.summarise_llm.to_dict()

        doctag_llm: dict[str, Any] | Unset = UNSET
        if not isinstance(self.doctag_llm, Unset):
            doctag_llm = self.doctag_llm.to_dict()

        artifact_llm: dict[str, Any] | Unset = UNSET
        if not isinstance(self.artifact_llm, Unset):
            artifact_llm = self.artifact_llm.to_dict()

        model_citation: dict[str, Any] | Unset = UNSET
        if not isinstance(self.model_citation, Unset):
            model_citation = self.model_citation.to_dict()

        retriever: dict[str, Any] | Unset = UNSET
        if not isinstance(self.retriever, Unset):
            retriever = self.retriever.to_dict()

        reranker: dict[str, Any] | Unset = UNSET
        if not isinstance(self.reranker, Unset):
            reranker = self.reranker.to_dict()

        parser: dict[str, Any] | Unset = UNSET
        if not isinstance(self.parser, Unset):
            parser = self.parser.to_dict()

        chunker: dict[str, Any] | Unset = UNSET
        if not isinstance(self.chunker, Unset):
            chunker = self.chunker.to_dict()

        embedder: dict[str, Any] | Unset = UNSET
        if not isinstance(self.embedder, Unset):
            embedder = self.embedder.to_dict()

        keyword_embedder: dict[str, Any] | Unset = UNSET
        if not isinstance(self.keyword_embedder, Unset):
            keyword_embedder = self.keyword_embedder.to_dict()

        field_dict: dict[str, Any] = {}
        field_dict.update(self.additional_properties)
        field_dict.update({})
        if agents is not UNSET:
            field_dict["Agents"] = agents
        if query_llm is not UNSET:
            field_dict["QueryLLM"] = query_llm
        if evaluator_llm is not UNSET:
            field_dict["EvaluatorLLM"] = evaluator_llm
        if title_llm is not UNSET:
            field_dict["TitleLLM"] = title_llm
        if summarise_llm is not UNSET:
            field_dict["SummariseLLM"] = summarise_llm
        if doctag_llm is not UNSET:
            field_dict["DoctagLLM"] = doctag_llm
        if artifact_llm is not UNSET:
            field_dict["ArtifactLLM"] = artifact_llm
        if model_citation is not UNSET:
            field_dict["ModelCitation"] = model_citation
        if retriever is not UNSET:
            field_dict["Retriever"] = retriever
        if reranker is not UNSET:
            field_dict["Reranker"] = reranker
        if parser is not UNSET:
            field_dict["Parser"] = parser
        if chunker is not UNSET:
            field_dict["Chunker"] = chunker
        if embedder is not UNSET:
            field_dict["Embedder"] = embedder
        if keyword_embedder is not UNSET:
            field_dict["KeywordEmbedder"] = keyword_embedder

        return field_dict

    @classmethod
    def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
        from ..models.agents_config import AgentsConfig
        from ..models.artifact_llm_config import ArtifactLLMConfig
        from ..models.chunker_config import ChunkerConfig
        from ..models.doctag_llm_config import DoctagLLMConfig
        from ..models.embedder_config import EmbedderConfig
        from ..models.evaluator_llm_config import EvaluatorLLMConfig
        from ..models.keyword_embedder_config import KeywordEmbedderConfig
        from ..models.model_citation_config import ModelCitationConfig
        from ..models.parser_config import ParserConfig
        from ..models.query_llm_config import QueryLLMConfig
        from ..models.reranker_config import RerankerConfig
        from ..models.retriever_config import RetrieverConfig
        from ..models.summarise_llm_config import SummariseLLMConfig
        from ..models.title_llm_config import TitleLLMConfig

        d = dict(src_dict)
        _agents = d.pop("Agents", UNSET)
        agents: AgentsConfig | Unset
        if isinstance(_agents, Unset):
            agents = UNSET
        else:
            agents = AgentsConfig.from_dict(_agents)

        _query_llm = d.pop("QueryLLM", UNSET)
        query_llm: QueryLLMConfig | Unset
        if isinstance(_query_llm, Unset):
            query_llm = UNSET
        else:
            query_llm = QueryLLMConfig.from_dict(_query_llm)

        _evaluator_llm = d.pop("EvaluatorLLM", UNSET)
        evaluator_llm: EvaluatorLLMConfig | Unset
        if isinstance(_evaluator_llm, Unset):
            evaluator_llm = UNSET
        else:
            evaluator_llm = EvaluatorLLMConfig.from_dict(_evaluator_llm)

        _title_llm = d.pop("TitleLLM", UNSET)
        title_llm: TitleLLMConfig | Unset
        if isinstance(_title_llm, Unset):
            title_llm = UNSET
        else:
            title_llm = TitleLLMConfig.from_dict(_title_llm)

        _summarise_llm = d.pop("SummariseLLM", UNSET)
        summarise_llm: SummariseLLMConfig | Unset
        if isinstance(_summarise_llm, Unset):
            summarise_llm = UNSET
        else:
            summarise_llm = SummariseLLMConfig.from_dict(_summarise_llm)

        _doctag_llm = d.pop("DoctagLLM", UNSET)
        doctag_llm: DoctagLLMConfig | Unset
        if isinstance(_doctag_llm, Unset):
            doctag_llm = UNSET
        else:
            doctag_llm = DoctagLLMConfig.from_dict(_doctag_llm)

        _artifact_llm = d.pop("ArtifactLLM", UNSET)
        artifact_llm: ArtifactLLMConfig | Unset
        if isinstance(_artifact_llm, Unset):
            artifact_llm = UNSET
        else:
            artifact_llm = ArtifactLLMConfig.from_dict(_artifact_llm)

        _model_citation = d.pop("ModelCitation", UNSET)
        model_citation: ModelCitationConfig | Unset
        if isinstance(_model_citation, Unset):
            model_citation = UNSET
        else:
            model_citation = ModelCitationConfig.from_dict(_model_citation)

        _retriever = d.pop("Retriever", UNSET)
        retriever: RetrieverConfig | Unset
        if isinstance(_retriever, Unset):
            retriever = UNSET
        else:
            retriever = RetrieverConfig.from_dict(_retriever)

        _reranker = d.pop("Reranker", UNSET)
        reranker: RerankerConfig | Unset
        if isinstance(_reranker, Unset):
            reranker = UNSET
        else:
            reranker = RerankerConfig.from_dict(_reranker)

        _parser = d.pop("Parser", UNSET)
        parser: ParserConfig | Unset
        if isinstance(_parser, Unset):
            parser = UNSET
        else:
            parser = ParserConfig.from_dict(_parser)

        _chunker = d.pop("Chunker", UNSET)
        chunker: ChunkerConfig | Unset
        if isinstance(_chunker, Unset):
            chunker = UNSET
        else:
            chunker = ChunkerConfig.from_dict(_chunker)

        _embedder = d.pop("Embedder", UNSET)
        embedder: EmbedderConfig | Unset
        if isinstance(_embedder, Unset):
            embedder = UNSET
        else:
            embedder = EmbedderConfig.from_dict(_embedder)

        _keyword_embedder = d.pop("KeywordEmbedder", UNSET)
        keyword_embedder: KeywordEmbedderConfig | Unset
        if isinstance(_keyword_embedder, Unset):
            keyword_embedder = UNSET
        else:
            keyword_embedder = KeywordEmbedderConfig.from_dict(_keyword_embedder)

        all_configs = cls(
            agents=agents,
            query_llm=query_llm,
            evaluator_llm=evaluator_llm,
            title_llm=title_llm,
            summarise_llm=summarise_llm,
            doctag_llm=doctag_llm,
            artifact_llm=artifact_llm,
            model_citation=model_citation,
            retriever=retriever,
            reranker=reranker,
            parser=parser,
            chunker=chunker,
            embedder=embedder,
            keyword_embedder=keyword_embedder,
        )

        all_configs.additional_properties = d
        return all_configs

    @property
    def additional_keys(self) -> list[str]:
        return list(self.additional_properties.keys())

    def __getitem__(self, key: str) -> Any:
        return self.additional_properties[key]

    def __setitem__(self, key: str, value: Any) -> None:
        self.additional_properties[key] = value

    def __delitem__(self, key: str) -> None:
        del self.additional_properties[key]

    def __contains__(self, key: str) -> bool:
        return key in self.additional_properties
