# coding: utf-8

"""
    Mixpeek API

    This is the Mixpeek API, providing access to various endpoints for data processing and retrieval.

    The version of the OpenAPI document: 1.3.0
    Contact: info@mixpeek.com
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501


from __future__ import annotations
import pprint
import re  # noqa: F401
import json

from pydantic import BaseModel, ConfigDict, Field, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from typing_extensions import Annotated
from mixpeek.models.components_config import ComponentsConfig
from mixpeek.models.custom_cta import CustomCTA
from mixpeek.models.external_link import ExternalLink
from mixpeek.models.field_config import FieldConfig
from mixpeek.models.input_rendering_config_input import InputRenderingConfigInput
from mixpeek.models.layout_config import LayoutConfig
from mixpeek.models.markdown_content import MarkdownContent
from mixpeek.models.seo_config import SEOConfig
from mixpeek.models.theme_config import ThemeConfig
from typing import Optional, Set
from typing_extensions import Self

class DisplayConfigInput(BaseModel):
    """
    Display configuration for public retriever UI.  This model defines how the public search interface should be rendered, including input fields, theme, layout, and result card configuration.  The frontend (apps.mixpeek.com) uses this to dynamically build the UI without hardcoded components.
    """ # noqa: E501
    title: StrictStr = Field(description="Title/heading for the public search page")
    description: Optional[StrictStr] = Field(default=None, description="Optional description/subtitle for the page")
    logo_url: Optional[StrictStr] = Field(default=None, description="URL to logo image")
    icon_base64: Optional[Annotated[str, Field(strict=True, max_length=300000)]] = Field(default=None, description="Base64 encoded icon/favicon (data URI format recommended). Max size: ~200KB encoded. Use for small icons that should be embedded. Example: 'data:image/png;base64,iVBORw0KGgo...'")
    seo: Optional[SEOConfig] = Field(default=None, description="SEO configuration for search engine and social media discoverability. Auto-generated during publishing with sensible defaults inferred from title, description, and retriever metadata. All fields can be overridden.")
    markdowns: Optional[List[MarkdownContent]] = Field(default=None, description="Array of markdown content sections for documentation, guides, or informational modals. Each section has a title and markdown-formatted content. Displayed in modals, expandable sections, or tabs on the public interface. Examples: 'How it Works', 'Search Guide', 'About', 'FAQ', etc.")
    theme: Optional[ThemeConfig] = Field(default=None, description="Theme/styling configuration")
    inputs: List[InputRenderingConfigInput] = Field(description="List of input fields to render in the search interface. Each input maps to a field in the retriever's input_schema. Frontend uses the field_schema to render the appropriate component type.")
    layout: Optional[LayoutConfig] = Field(default=None, description="Layout configuration for results")
    exposed_fields: Annotated[List[StrictStr], Field(min_length=1)] = Field(description="List of document metadata fields to show in results. Only these fields are returned to end users.")
    components: Optional[ComponentsConfig] = Field(default=None, description="Configuration for UI components including search inputs, filters, and result card display options.")
    field_config: Optional[Dict[str, FieldConfig]] = Field(default=None, description="Configuration for how each field should be displayed. Keys are field names (must be subset of exposed_fields). Values are FieldConfig objects specifying format and display options.")
    custom_cta: Optional[CustomCTA] = Field(default=None, description="Optional custom call-to-action button displayed in the header bar. Opens a markdown modal when clicked.")
    external_links: Optional[List[ExternalLink]] = Field(default=None, description="External resource links for this retriever (GitHub repos, blog posts, docs, etc.). Displayed on homepage and retriever listing pages to provide additional context.")
    template_type: Optional[StrictStr] = Field(default=None, description="Template identifier for frontend rendering. Built-in templates: portrait-gallery, media-search, document-search. Custom templates can use any string identifier.")
    field_mappings: Optional[Dict[str, StrictStr]] = Field(default=None, description="Field mappings from collection output fields to template display slots. Maps template slot names (e.g., 'thumbnail', 'title') to actual field names in the search results.")
    extensions: Optional[Dict[str, Any]] = Field(default=None, description="Generic extensions for template-specific configuration. Allows templates to store custom config without schema changes.")
    additional_properties: Dict[str, Any] = {}
    __properties: ClassVar[List[str]] = ["title", "description", "logo_url", "icon_base64", "seo", "markdowns", "theme", "inputs", "layout", "exposed_fields", "components", "field_config", "custom_cta", "external_links", "template_type", "field_mappings", "extensions"]

    model_config = ConfigDict(
        populate_by_name=True,
        validate_assignment=True,
        protected_namespaces=(),
    )


    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.model_dump(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of DisplayConfigInput from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        * Fields in `self.additional_properties` are added to the output dict.
        """
        excluded_fields: Set[str] = set([
            "additional_properties",
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of seo
        if self.seo:
            _dict['seo'] = self.seo.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in markdowns (list)
        _items = []
        if self.markdowns:
            for _item_markdowns in self.markdowns:
                if _item_markdowns:
                    _items.append(_item_markdowns.to_dict())
            _dict['markdowns'] = _items
        # override the default output from pydantic by calling `to_dict()` of theme
        if self.theme:
            _dict['theme'] = self.theme.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in inputs (list)
        _items = []
        if self.inputs:
            for _item_inputs in self.inputs:
                if _item_inputs:
                    _items.append(_item_inputs.to_dict())
            _dict['inputs'] = _items
        # override the default output from pydantic by calling `to_dict()` of layout
        if self.layout:
            _dict['layout'] = self.layout.to_dict()
        # override the default output from pydantic by calling `to_dict()` of components
        if self.components:
            _dict['components'] = self.components.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each value in field_config (dict)
        _field_dict = {}
        if self.field_config:
            for _key_field_config in self.field_config:
                if self.field_config[_key_field_config]:
                    _field_dict[_key_field_config] = self.field_config[_key_field_config].to_dict()
            _dict['field_config'] = _field_dict
        # override the default output from pydantic by calling `to_dict()` of custom_cta
        if self.custom_cta:
            _dict['custom_cta'] = self.custom_cta.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in external_links (list)
        _items = []
        if self.external_links:
            for _item_external_links in self.external_links:
                if _item_external_links:
                    _items.append(_item_external_links.to_dict())
            _dict['external_links'] = _items
        # puts key-value pairs in additional_properties in the top level
        if self.additional_properties is not None:
            for _key, _value in self.additional_properties.items():
                _dict[_key] = _value

        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of DisplayConfigInput from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
            "title": obj.get("title"),
            "description": obj.get("description"),
            "logo_url": obj.get("logo_url"),
            "icon_base64": obj.get("icon_base64"),
            "seo": SEOConfig.from_dict(obj["seo"]) if obj.get("seo") is not None else None,
            "markdowns": [MarkdownContent.from_dict(_item) for _item in obj["markdowns"]] if obj.get("markdowns") is not None else None,
            "theme": ThemeConfig.from_dict(obj["theme"]) if obj.get("theme") is not None else None,
            "inputs": [InputRenderingConfigInput.from_dict(_item) for _item in obj["inputs"]] if obj.get("inputs") is not None else None,
            "layout": LayoutConfig.from_dict(obj["layout"]) if obj.get("layout") is not None else None,
            "exposed_fields": obj.get("exposed_fields"),
            "components": ComponentsConfig.from_dict(obj["components"]) if obj.get("components") is not None else None,
            "field_config": dict(
                (_k, FieldConfig.from_dict(_v))
                for _k, _v in obj["field_config"].items()
            )
            if obj.get("field_config") is not None
            else None,
            "custom_cta": CustomCTA.from_dict(obj["custom_cta"]) if obj.get("custom_cta") is not None else None,
            "external_links": [ExternalLink.from_dict(_item) for _item in obj["external_links"]] if obj.get("external_links") is not None else None,
            "template_type": obj.get("template_type"),
            "field_mappings": obj.get("field_mappings"),
            "extensions": obj.get("extensions")
        })
        # store additional fields in additional_properties
        for _key in obj.keys():
            if _key not in cls.__properties:
                _obj.additional_properties[_key] = obj.get(_key)

        return _obj


