from __future__ import annotations
from dataclasses import dataclass, field, asdict
from typing import Optional

@dataclass(order=True)  # order=True automatically generates __lt__, __le__, etc.
class Point:
    """
    Represents a specific depth within a soil profile.
    Automatically sortable by depth.
    """
    # depth is the primary field used for sorting (due to order=True)
    depth: float
    
    # Metadata fields excluded from comparisons and the default repr
    total_stress: Optional[float] = field(default=None, repr=False, compare=False)
    pore_pressure: Optional[float] = field(default=None, repr=False, compare=False)
    effective_stress: Optional[float] = field(default=None, repr=False, compare=False)
    active_earth_pressure: Optional[float] = field(default=None, repr=False, compare=False)
    passive_earth_pressure: Optional[float] = field(default=None, repr=False, compare=False)
    layer_index: Optional[int] = field(default=None, repr=False, compare=False)

    def __post_init__(self) -> None:
        if self.depth < 0:
            raise ValueError(f"Depth must be >= 0, got {self.depth!r}")

    @property
    def is_computed(self) -> bool:
        return self.total_stress is not None

    def __repr__(self) -> str:
        if self.is_computed:
            base = (f"Point(depth={self.depth}, σ_v={self.total_stress:.2f}, "
                    f"u={self.pore_pressure:.2f}, σ'_v={self.effective_stress:.2f}, layer_index={self.layer_index}")
            if self.active_earth_pressure is not None:
                base += f", σ_a={self.active_earth_pressure:.2f}"
            if self.passive_earth_pressure is not None:
                base += f", σ_p={self.passive_earth_pressure:.2f}"
            return base + ")"
        return f"Point(depth={self.depth}, [not computed])"

    def to_dict(self) -> dict:
        """Standardizes dictionary export using dataclass utilities."""
        return asdict(self)