"""
RGD-PHYSICS :: AION-128 (The Spark)
16-Byte Vital Unit. Ultra-compressed for IoT and Swarms.
"""
import struct
from dataclasses import dataclass
from typing import Tuple

@dataclass(frozen=True, slots=True)
class Aion128:
    """
    The Light Aion (Smart Dust Isotope).
    Total Size: 16 Bytes.
    
    Structure (2 x 64-bit Integers):
    [0] Header (64-bit):
        - 32-bit Anchor (Timestamp)
        - 32-bit ID (Entity Hash)
    [1] Geo Packed (64-bit):
        - 4 x 16-bit Half-Precision Floats (X, Y, Z, W)
    
    NO Payload field. The existence IS the message.
    """
    header: int
    geo_packed: int

    @property
    def aion_class(self) -> str:
        return "LIGHT (128-bit)"

    # --- PROTOCOL IMPLEMENTATION ---

    @property
    def anchor(self) -> int:
        """Extracts the Timestamp portion (upper 32 bits) of the header."""
        return (self.header >> 32) & 0xFFFFFFFF

    @property
    def laws_encoded(self) -> int:
        """
        Light Aions have no space for metadata laws.
        Returns 0 (Newtonian Default / Passive Observer).
        """
        return 0

    @property
    def metric_coordinates(self) -> Tuple[float, float, float, float]:
        """
        Unpacks 4 half-precision floats (16-bit) from the 64-bit integer.
        Uses Python's struct 'e' format (IEEE 754 binary16).
        """
        # Convert integer to 8 bytes
        geo_bytes = self.geo_packed.to_bytes(8, byteorder='big')
        # Unpack as 4 float16
        return struct.unpack('!4e', geo_bytes)

    @property
    def payload_hash(self) -> int:
        """
        The Light Aion has no payload. 
        Its Identity (Header) acts as its hash.
        """
        return self.header

    # --- ZERO-COPY SERIALIZATION ---
    
    # Format: 2 Unsigned Long Longs (16 Bytes)
    _STRUCT = struct.Struct('!2Q')

    def to_bytes(self) -> bytes:
        return self._STRUCT.pack(self.header, self.geo_packed)

    @classmethod
    def from_bytes(cls, buffer: bytes) -> 'Aion128':
        unpacked = cls._STRUCT.unpack(buffer)
        return cls(*unpacked)