from __future__ import annotations

from pydantic import BaseModel


class Node(BaseModel):
    id: int
    termType: str  # "uri" | "bnode"
    iri: str
    label: str | None = None
    # Optional because /api/nodes (RDFStore) doesn't currently provide positions.
    x: float | None = None
    y: float | None = None


class Edge(BaseModel):
    source: int
    target: int
    predicate: str


class StatsResponse(BaseModel):
    backend: str
    ttl_path: str
    sparql_endpoint: str | None = None
    parsed_triples: int
    nodes: int
    edges: int


class NodesResponse(BaseModel):
    total: int
    nodes: list[Node]


class EdgesResponse(BaseModel):
    total: int
    edges: list[Edge]


class GraphResponse(BaseModel):
    class Meta(BaseModel):
        backend: str
        ttl_path: str | None = None
        sparql_endpoint: str | None = None
        include_bnodes: bool
        node_limit: int
        edge_limit: int
        nodes: int
        edges: int

    nodes: list[Node]
    edges: list[Edge]
    meta: Meta | None = None


class SparqlQueryRequest(BaseModel):
    query: str


class NeighborsRequest(BaseModel):
    selected_ids: list[int]
    node_limit: int = 50_000
    edge_limit: int = 100_000


class NeighborsResponse(BaseModel):
    selected_ids: list[int]
    neighbor_ids: list[int]
