"""Specialized data types for GQLDB Python driver."""

from dataclasses import dataclass, field
from datetime import datetime, timezone
from typing import List


@dataclass
class Point:
    """2D geographic point."""
    latitude: float
    longitude: float


@dataclass
class Point3D:
    """3D point."""
    x: float
    y: float
    z: float


@dataclass
class GqldbDecimal:
    """High-precision decimal number."""
    value: str


@dataclass
class GqldbLocalDateTime:
    """Local date-time without timezone, stored as components."""
    year: int
    month: int  # 1-12
    day: int  # 1-31
    hour: int  # 0-23
    minute: int  # 0-59
    second: int  # 0-59
    nanosecond: int = 0  # 0-999999999

    def to_datetime(self) -> datetime:
        """Convert to a datetime (no timezone).

        The returned datetime uses the stored components directly.
        Microsecond precision only (nanoseconds are truncated to microseconds).
        """
        return datetime(
            self.year, self.month, self.day,
            self.hour, self.minute, self.second,
            self.nanosecond // 1000,
        )

    def __str__(self) -> str:
        """Return ISO 8601 format without timezone (e.g., '2024-06-15T14:30:00')."""
        dt = self.to_datetime()
        if dt.microsecond:
            return dt.strftime("%Y-%m-%dT%H:%M:%S.") + f"{dt.microsecond:06d}"
        return dt.strftime("%Y-%m-%dT%H:%M:%S")


@dataclass
class GqldbZonedDateTime:
    """Date-time with timezone offset, stored as components."""
    year: int
    month: int  # 1-12
    day: int  # 1-31
    hour: int  # 0-23
    minute: int  # 0-59
    second: int  # 0-59
    nanosecond: int = 0  # 0-999999999
    offset_minutes: int = 0  # UTC offset in minutes (signed)

    def to_datetime(self) -> datetime:
        """Convert to a timezone-aware datetime.

        The returned datetime uses the stored components with the timezone offset applied.
        Microsecond precision only (nanoseconds are truncated to microseconds).
        """
        from datetime import timedelta
        tz = timezone(timedelta(minutes=self.offset_minutes))
        return datetime(
            self.year, self.month, self.day,
            self.hour, self.minute, self.second,
            self.nanosecond // 1000,
            tzinfo=tz,
        )


@dataclass
class GqldbDate:
    """Date without time."""
    year: int
    month: int  # 1-12
    day: int  # 1-31


@dataclass
class GqldbLocalTime:
    """Local time without timezone."""
    hour: int
    minute: int
    second: int
    nanosecond: int


@dataclass
class GqldbZonedTime:
    """Time with timezone offset."""
    hour: int
    minute: int
    second: int
    nanosecond: int
    offset_minutes: int


@dataclass
class YearToMonth:
    """Year-month interval."""
    months: int  # total months (can be negative)


@dataclass
class DayToSecond:
    """Day-second interval."""
    seconds: int
    nanoseconds: int


@dataclass
class Vector:
    """Float32 vector for embeddings."""
    values: List[float] = field(default_factory=list)


@dataclass
class GqldbTable:
    """Table data with columns and rows."""
    columns: List[str] = field(default_factory=list)
    rows: List[List] = field(default_factory=list)
    column_types: List[int] = field(default_factory=list)


@dataclass
class ComputeTopologyResult:
    """Result of wait_for_compute_topology operation."""
    ready: bool
    message: str
