from pydantic import BaseModel, Field

from emmet.core.synthesis.materials import ExtractedMaterial
from emmet.core.synthesis.operations import Operation
from emmet.core.synthesis.reaction import ReactionFormula
from emmet.core.types.enums import ValueEnum


class SynthesisTypeEnum(str, ValueEnum):
    solid_state = "solid-state"
    sol_gel = "sol-gel"


class SynthesisRecipe(BaseModel):
    """
    Model for a document containing synthesis description data
    """

    # Basic facts about this recipe:
    doi: str | None = Field(None, description="DOI of the journal article.")
    paragraph_string: str | None = Field(
        "", description="The paragraph from which this recipe is extracted."
    )
    synthesis_type: SynthesisTypeEnum | None = Field(
        None, description="Type of the synthesis recipe."
    )
    # Reaction related information:
    reaction_string: str | None = Field(
        None, description="String representation of this recipe."
    )
    reaction: ReactionFormula | None = Field(
        None, description="The balanced reaction formula."
    )
    target: ExtractedMaterial | None = Field(None, description="The target material.")
    targets_formula: list[str] | None = Field(
        None, description="List of synthesized target material compositions."
    )
    precursors_formula: list[str] | None = Field(
        None, description="List of precursor material compositions."
    )
    targets_formula_s: list[str] | None = Field(
        None,
        description="List of synthesized target material compositions, as strings.",
    )
    precursors_formula_s: list[str] | None = Field(
        None, description="List of precursor material compositions, as strings."
    )
    precursors: list[ExtractedMaterial] | None = Field(
        None, description="List of precursor materials."
    )
    operations: list[Operation] | None = Field(
        None, description="List of operations used to synthesize this recipe."
    )


class AtlasSearchText(BaseModel):
    """Schematize MongoDB Atlas search text match."""

    value: str | None = None
    type: str | None = None


class AtlasSearchHighlight(BaseModel):
    """Schematize MongoDB Atlas search highlight match."""

    score: float | None = None
    path: str | None = None
    texts: list[AtlasSearchText] | None = None


class SynthesisSearchResultModel(SynthesisRecipe):
    """
    Model for a document containing synthesis recipes
    data and additional keyword search results
    """

    search_score: float | None = Field(
        None,
        description="Search score.",
    )
    highlights: list[AtlasSearchHighlight] | None = Field(
        None,
        description="Search highlights.",
    )
