"""
src/export/edl_writer.py — EditTimeline → CMX 3600 EDL

Generates a standard CMX 3600 Edit Decision List compatible with
Avid, DaVinci Resolve, Premiere Pro, and most NLEs.

CMX 3600 format reference:
  https://en.wikipedia.org/wiki/Edit_decision_list#CMX_3600
"""

from __future__ import annotations

import logging
from pathlib import Path

from src.core.config import AppConfig
from src.core.models import EditClip, EditTimeline
from src.export.timecode import seconds_to_smpte

logger = logging.getLogger(__name__)


# ---------------------------------------------------------------------------
# EDL line builders
# ---------------------------------------------------------------------------

def _edl_header(title: str) -> str:
    return f"TITLE: {title}\nFCM: NON-DROP FRAME\n"


def _edl_event(
    event_num: int,
    clip: EditClip,
    fps: float,
) -> str:
    """
    Build one CMX 3600 event block for a single clip.

    Format:
        NNN  AX  V  C  <SRC_IN> <SRC_OUT> <REC_IN> <REC_OUT>
        * FROM CLIP NAME: ...
        * COMMENT: ...
    """
    src_in  = seconds_to_smpte(clip.match.in_point_s,         fps)
    source_duration_s = clip.source_timeline_duration_s
    src_out = seconds_to_smpte(clip.match.in_point_s + source_duration_s, fps)
    rec_in  = seconds_to_smpte(clip.timeline_start_s,         fps)
    rec_out = seconds_to_smpte(clip.timeline_start_s + source_duration_s, fps)

    event_line  = f"{event_num:03d}  AX       V     C        {src_in} {src_out} {rec_in} {rec_out}"
    name_line   = f"* FROM CLIP NAME:  {clip.match.source_path.name}"
    comment_line = (
        f"* BEAT {clip.beat.beat_id:03d} | {clip.beat.beat_type.name} | "
        f"score={clip.match.match_score:.3f}"
    )

    return "\n".join([event_line, name_line, comment_line, ""])


def _edl_black_tail_event(event_num: int, clip: EditClip, fps: float) -> str:
    rec_in = seconds_to_smpte(clip.timeline_start_s + clip.source_timeline_duration_s, fps)
    rec_out = seconds_to_smpte(clip.timeline_end_s, fps)
    event_line = f"{event_num:03d}  BL       V     C        00:00:00:00 00:00:00:00 {rec_in} {rec_out}"
    comment_line = (
        f"* BEAT {clip.beat.beat_id:03d} TRAILER-ONLY TAIL | "
        "add fade/dissolve to black"
    )
    return "\n".join([event_line, "* FROM CLIP NAME:  BLACK", comment_line, ""])


# ---------------------------------------------------------------------------
# Public API
# ---------------------------------------------------------------------------

def write_edl(
    timeline: EditTimeline,
    cfg: AppConfig,
    output_path: Path | None = None,
) -> Path:
    """
    Write the EditTimeline as a CMX 3600 EDL file.

    Args:
        timeline:    EditTimeline from build_timeline().
        cfg:         Application configuration.
        output_path: Override destination. Defaults to
                     <output_dir>/<project_name>.edl.

    Returns:
        Path to the written .edl file.
    """
    if output_path is None:
        output_path = cfg.paths.output_dir / f"{timeline.title}.edl"

    output_path.parent.mkdir(parents=True, exist_ok=True)

    fps    = timeline.frame_rate
    lines  = [_edl_header(timeline.title), "\n"]

    event_num = 1
    for clip in sorted(timeline.clips, key=lambda c: c.clip_index):
        lines.append(_edl_event(event_num, clip, fps))
        event_num += 1
        if clip.trailer_tail_s > 0:
            lines.append("\n")
            lines.append(_edl_black_tail_event(event_num, clip, fps))
            event_num += 1
        lines.append("\n")

    edl_text = "\n".join(lines)
    output_path.write_text(edl_text, encoding="utf-8")

    logger.info("EDL written → %s (%d events)", output_path, timeline.clip_count)
    return output_path
