from dataclasses import dataclass, field
from typing import Any, Self

from vstools import FieldBased, FieldBasedT, SPath, SPathLike, vs

from ..components import (
    CombedFrames,
    CustomLists,
    Decimations,
    FieldMatches,
    FreezeFrames,
    InterlacedFades,
    OrphanFrames,
    Presets,
    Sections,
    WobblyVideo,
)

__all__ = [
    'WobblyParser',
]


@dataclass
class WobblyParser:
    """Class for parsing wobbly files."""

    file_path: SPath
    """The path to the wobbly file."""

    work_clip: vs.VideoNode
    """The clip to work on."""

    video_data: WobblyVideo
    """Source clip information."""

    field_order: FieldBasedT = FieldBased.TFF
    """Field order of the source clip."""

    sections: Sections = field(default_factory=Sections)
    """Sections of the wobbly file."""

    field_matches: FieldMatches = field(default_factory=FieldMatches)
    """List of field matches."""

    decimations: Decimations = field(default_factory=Decimations)
    """List of frames to decimate."""

    presets: Presets = field(default_factory=Presets)
    """List of filtering presets."""

    custom_lists: CustomLists = field(default_factory=CustomLists)
    """List of custom filtering ranges."""

    freeze_frames: FreezeFrames = field(default_factory=FreezeFrames)
    """List of freeze frames."""

    interlaced_fades: InterlacedFades = field(default_factory=InterlacedFades)
    """List of interlaced fades."""

    combed_frames: CombedFrames = field(default_factory=CombedFrames)
    """List of combed frames."""

    orphan_frames: OrphanFrames = field(default_factory=OrphanFrames)
    """List of orphan frames."""

    def __init__(
        self,
        file_path: SPath,
        work_clip: vs.VideoNode,
        video_data: WobblyVideo,
        field_order: FieldBasedT,
        sections: Sections | None = None,
        field_matches: FieldMatches | None = None,
        decimations: Decimations | None = None,
        presets: Presets | None = None,
        custom_lists: CustomLists | None = None,
        freeze_frames: FreezeFrames | None = None,
        interlaced_fades: InterlacedFades | None = None,
        combed_frames: CombedFrames | None = None,
        orphan_frames: OrphanFrames | None = None,
    ) -> None:
        self.file_path = file_path
        self.work_clip = work_clip
        self.video_data = video_data
        self.field_order = field_order

        self.sections = sections or Sections()
        self.field_matches = field_matches or FieldMatches()
        self.decimations = decimations or Decimations()
        self.presets = presets or Presets()
        self.custom_lists = custom_lists or CustomLists()
        self.freeze_frames = freeze_frames or FreezeFrames()
        self.interlaced_fades = interlaced_fades or InterlacedFades()
        self.combed_frames = combed_frames or CombedFrames()
        self.orphan_frames = orphan_frames or OrphanFrames()

    @classmethod
    def from_file(cls, file_path: SPathLike) -> Self:
        """Parse a wobbly object from a wobbly file."""

        from .builder import WobblyBuilder

        return WobblyBuilder(file_path).build()

    @staticmethod
    def _get_video_data(wob_file: SPath, data: dict[str, Any]) -> WobblyVideo:
        """Get the video data."""

        return WobblyVideo(wob_file.as_posix(), data.get('trim', None), data.get('source filter', ''))

    @staticmethod
    def _get_fieldbased_data(data: dict[str, Any]) -> FieldBasedT:
        """Get the fieldbased data."""

        vivtc_params = data.get('vfm parameters', {})
        order = bool(vivtc_params.get('order', 1))

        return FieldBased.from_param(order)
