from __future__ import annotations

from pathlib import Path
from typing import Annotated, Literal

from pydantic import Field

from ..domain.base import UXTGModel


class JsonInterval(UXTGModel):
    index: int
    x_min: float = Field(alias="xmin")
    x_max: float = Field(alias="xmax")
    text: str | None


class JsonPoint(UXTGModel):
    index: int
    number: float
    mark: str | None


class JsonIntervalTier(UXTGModel):
    tier_class: Literal["IntervalTier"] = Field(default="IntervalTier", alias="class")
    index: int
    name: str | None
    x_min: float = Field(alias="xmin")
    x_max: float = Field(alias="xmax")
    interval_count: int
    intervals: tuple[JsonInterval, ...] = ()


class JsonPointTier(UXTGModel):
    tier_class: Literal["TextTier"] = Field(default="TextTier", alias="class")
    index: int
    name: str | None
    x_min: float = Field(alias="xmin")
    x_max: float = Field(alias="xmax")
    point_count: int
    points: tuple[JsonPoint, ...] = ()


JsonTier = Annotated[JsonIntervalTier | JsonPointTier, Field(discriminator="tier_class")]


class TextGridJsonDocument(UXTGModel):
    file_type: Literal["ooTextFile"] = "ooTextFile"
    object_class: Literal["TextGrid"] = "TextGrid"
    x_min: float = Field(alias="xmin")
    x_max: float = Field(alias="xmax")
    tiers_exist: bool = True
    tier_count: int
    tiers: tuple[JsonTier, ...] = ()

    @classmethod
    def from_text(
        cls,
        text: str,
        *,
        round_digits: int = 5,
        strict: bool = True,
    ) -> "TextGridJsonDocument":
        from ..api import parse_textgrid, textgrid_to_json_document

        return textgrid_to_json_document(
            parse_textgrid(text, round_digits=round_digits, strict=strict)
        )

    @classmethod
    def from_file(
        cls,
        path: str | Path,
        *,
        round_digits: int = 5,
        strict: bool = True,
        encoding: str | None = None,
    ) -> "TextGridJsonDocument":
        from ..api import read_textgrid, textgrid_to_json_document

        return textgrid_to_json_document(
            read_textgrid(path, round_digits=round_digits, strict=strict, encoding=encoding)
        )
