"""Models specific to the E-NAUTILUS point method."""

from sqlmodel import JSON, Column, Field, SQLModel

from desdeo.tools import SolverResults


class ENautilusStepRequest(SQLModel):
    """Model of the request to the E-NAUTILUS method."""

    problem_id: int
    session_id: int | None = Field(default=None)
    parent_state_id: int | None = Field(default=None)
    # non_dominated points fetched from problem metadata in endpoints
    representative_solutions_id: int = Field(description="The id of the representative solutions to be used.")

    current_iteration: int = Field(description="The number of the current iteration.")
    iterations_left: int = Field(description="The number of iterations left.")
    selected_point: dict[str, float] | None = Field(
        sa_column=Column(JSON),
        description=(
            "The selected intermediate point. If first iteration, set this to be the (approximated) nadir point. "
            "If not set, then the point is assumed to be the nadir point of the current approximating set."
        ),
    )
    reachable_point_indices: list[int] = Field(
        description=(
            "The indices indicating the point on the non-dominated set that are "
            "reachable from the currently selected point."
        )
    )
    number_of_intermediate_points: int = Field(description="The number of intermediate points to be generated.")


class ENautilusStepResponse(SQLModel):
    """The response from E-NAUTILUS step endpoint."""

    state_id: int | None = Field(description="The id of the state created by the request that generated this response")

    current_iteration: int = Field(description="Number of the current iteration.")
    iterations_left: int = Field(description="Number of iterations left.")
    intermediate_points: list[dict[str, float]] = Field(sa_column=Column(JSON), description="New intermediate points")
    reachable_best_bounds: list[dict[str, float]] = Field(
        sa_column=Column(JSON),
        description="Best bounds of the objective function values reachable from each intermediate point.",
    )
    reachable_worst_bounds: list[dict[str, float]] = Field(
        sa_column=Column(JSON),
        description="Worst bounds of the objective function values reachable from each intermediate point.",
    )
    closeness_measures: list[float] = Field(description="Closeness measures of each intermediate point.")
    reachable_point_indices: list[list[int]] = Field(
        description="Indices of the reachable points from each intermediate point."
    )


class ENautilusStateResponse(SQLModel):
    """The response model when requesting a state in E-NAUTILUS."""

    request: ENautilusStepRequest = Field(description="The original request for generating the state.")
    response: ENautilusStepResponse = Field(description="The state generated by the request.")


class ENautilusRepresentativeSolutionsResponse(SQLModel):
    """Model of the response when requesting representative solutions from E-NAUTILUS."""

    solutions: list[SolverResults] = Field(
        description="The solutions on the non-dominated front closest to the intermediate points."
    )
