"""Graph data types returned by AGE queries."""

from __future__ import annotations

from collections.abc import Iterator
from dataclasses import dataclass, field
from typing import Any


@dataclass(frozen=True)
class Vertex:
    """A graph vertex (node) returned by a Cypher query."""

    id: int
    label: str
    properties: dict[str, Any] = field(default_factory=dict)

    def __getitem__(self, key: str) -> Any:
        return self.properties.get(key)

    def __repr__(self) -> str:
        return f"Vertex(label={self.label!r}, id={self.id}, properties={self.properties})"


@dataclass(frozen=True)
class Edge:
    """A graph edge (relationship) returned by a Cypher query."""

    id: int
    label: str
    start_id: int
    end_id: int
    properties: dict[str, Any] = field(default_factory=dict)

    def __getitem__(self, key: str) -> Any:
        return self.properties.get(key)

    def __repr__(self) -> str:
        return (
            f"Edge(label={self.label!r}, id={self.id}, "
            f"start_id={self.start_id}, end_id={self.end_id}, "
            f"properties={self.properties})"
        )


@dataclass(frozen=True)
class Path:
    """A graph path: alternating sequence of vertices and edges."""

    entities: tuple[Vertex | Edge, ...] = ()

    @property
    def vertices(self) -> list[Vertex]:
        return [e for e in self.entities if isinstance(e, Vertex)]

    @property
    def edges(self) -> list[Edge]:
        return [e for e in self.entities if isinstance(e, Edge)]

    def __len__(self) -> int:
        return len(self.entities)

    def __getitem__(self, index: int) -> Vertex | Edge:
        return self.entities[index]

    def __iter__(self) -> Iterator[Vertex | Edge]:
        return iter(self.entities)

    def __repr__(self) -> str:
        return f"Path(length={len(self.edges)})"
