"""ffmpeg scene 필터 기반 시각적 장면전환 감지.

화면이 확 바뀌는 지점(컷/앵글전환/B롤)을 찾아 그 timestamp(초, 소스 기준)를 반환.
draft 의 비디오 세그먼트를 이 지점에서 추가로 쪼개면, 말이 이어져도(무음 없음)
장면이 바뀌는 곳에 캡컷 편집 컷이 생긴다. 시간은 그대로라 자막 싱크에 영향 없음.
"""
from __future__ import annotations

import re
import subprocess
from typing import List, Tuple

Segment = Tuple[float, float]

_PTS = re.compile(r"pts_time:([\d.]+)")


def detect_scene_changes(video_path: str, *, threshold: float = 0.4) -> List[float]:
    """장면전환 timestamp(초, 소스 기준) 리스트. threshold=scene score(0~1) 임계.

    낮을수록 민감(과분할), 높을수록 큰 전환만. 0.4 = 실제 컷 위주.
    """
    cmd = [
        "ffmpeg", "-hide_banner", "-nostats", "-i", video_path,
        "-vf", f"select='gt(scene,{threshold})',showinfo",
        "-an", "-f", "null", "-",
    ]
    # showinfo 는 stderr 로 출력. silence.py 와 동일하게 stderr→stdout 병합.
    proc = subprocess.run(
        cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
        text=True, encoding="utf-8", errors="replace",
    )
    times: List[float] = []
    for line in (proc.stdout or "").splitlines():
        if "showinfo" not in line:
            continue
        m = _PTS.search(line)
        if m:
            times.append(float(m.group(1)))
    return sorted(set(times))


def split_clips_at_scenes(
    video_clips: List[Segment],
    scene_times: List[float],
    *,
    min_len: float = 0.4,
) -> List[Segment]:
    """보존 구간(소스 시간)을 장면전환 지점에서 추가로 분할.

    인접 분할이라 누적 길이·타임라인 매핑이 동일 → 자막 싱크 영향 없음.
    분할 후 min_len 미만 조각은 앞 조각과 병합(너무 잘게 쪼개짐 방지).
    """
    if not scene_times:
        return video_clips
    out: List[Segment] = []
    for s, e in video_clips:
        # 이 구간 내부의 장면전환 지점만(양끝 여유 배제)
        cuts = [t for t in scene_times if s + min_len <= t <= e - min_len]
        if not cuts:
            out.append((s, e))
            continue
        prev = s
        for t in cuts:
            if t - prev >= min_len:
                out.append((prev, t))
                prev = t
        out.append((prev, e))
    return out
