from __future__ import annotations

from pygui.backend.models.frame import Frame
from pygui.backend.wafer.zwafer_models import ZWaferData


def frames_from_wafer_data(data: ZWaferData | None, records) -> list[Frame]:
    """Build Frames from parsed DataRecords (records = list[DataRecord].)"""
    return [Frame(seq=i, time=r.time, values=list(r.values)) for i, r in enumerate(records)]


def all_sensor_series(frames: list[Frame]) -> tuple[list[str], list[list[float]]]:
    """Per-sensor value series across every frame, for the whole-run Graph tab.

    Sensor names are 1-based ("Sensor 1", ...), matching the C# original.
    """
    if not frames:
        return [], []
    n_sensors = len(frames[0].values)
    names = [f"Sensor {i + 1}" for i in range(n_sensors)]
    series = [[frame.values[i] for frame in frames] for i in range(n_sensors)]
    return names, series

class FramePlayer:
    def __init__(self) -> None:
        self._frames: list[Frame] =[]
        self._i =0

    def load(self, frames: list[Frame]) -> "FramePlayer":
        self._frames = frames
        self._i = 0
        return self

    @property
    def total(self) -> int:
        return len(self._frames)

    @property
    def frames(self) -> tuple[Frame, ...]:
        return tuple(self._frames)

    @property
    def index(self) -> int:
        return self._i

    @property
    def at_end(self) -> bool:
        return self._i >= len(self._frames) -1

    def current(self) -> Frame | None:
        if not self._frames:
            return None
        return self._frames[self._i]

    def _clamp(self, i:int):
        return max(0, min(i, len(self._frames) - 1)) if self._frames else 0

    def step(self, delta: int) -> "FramePlayer":
        self._i = self._clamp(self._i + delta)
        return self

    def seek(self, i: int) -> "FramePlayer":
        self._i = self._clamp(i)
        return self

    def next_frame_ms(self) -> float:
        """Wall-clock ms until the next frame based on recorded timestamps; 0 if at end."""
        if self._i + 1 >= len(self._frames):
            return 0.0
        return (self._frames[self._i + 1].time - self._frames[self._i].time) * 1000.0
