"""FFmpeg/FFprobe yardımcı fonksiyonları."""
from __future__ import annotations
from pathlib import Path
from typing import List, Tuple
import subprocess

FFMPEG = "ffmpeg"
FFPROBE = "ffprobe"

# Windows'ta console açılmasını engelle
if __import__("sys").platform == "win32":
    _YARATMA_BAYRAGI = 0x08000000  # CREATE_NO_WINDOW
else:
    _YARATMA_BAYRAGI = 0


def _calistir(cmd: List[str], **kw) -> subprocess.CompletedProcess:
    return subprocess.run(cmd, capture_output=True, text=True,
                          creationflags=_YARATMA_BAYRAGI, **kw)


def ses_suresi(ses_yolu: str | Path) -> float:
    r = _calistir([
        FFPROBE, "-v", "error",
        "-show_entries", "format=duration",
        "-of", "default=noprint_wrappers=1:nokey=1",
        str(ses_yolu),
    ])
    try:
        return float(r.stdout.strip())
    except ValueError:
        return 0.0


def sesi_segmentlere_bol(ses_yolu: str | Path,
                         cikis_dizini: str | Path,
                         segment_sure: int) -> List[Tuple[Path, float, float, float]]:
    """Sesi eşit parçalara böler. Son parça >=5s ise ayrı segment açar.

    Returns:
        [(yol, baslangic, bitis, gercek_sure), ...]
    """
    cikis_dizini = Path(cikis_dizini)
    cikis_dizini.mkdir(parents=True, exist_ok=True)

    toplam = ses_suresi(ses_yolu)
    adet = int(toplam // segment_sure)
    kalan = toplam % segment_sure
    if kalan >= 5.0:
        adet += 1

    segmentler: List[Tuple[Path, float, float, float]] = []
    for i in range(adet):
        bas = i * segment_sure
        bit = min((i + 1) * segment_sure, toplam)
        sure = bit - bas
        cikis = cikis_dizini / f"ses_segment_{i:03d}.mp3"
        _calistir([
            FFMPEG, "-y", "-i", str(ses_yolu),
            "-ss", str(bas), "-t", str(sure),
            "-acodec", "libmp3lame", "-b:a", "192k",
            str(cikis),
        ], check=True)
        segmentler.append((cikis, bas, bit, sure))
    return segmentler


def son_kare_cikar(video_yolu: str | Path, cikis_resim: str | Path) -> bool:
    sure = _calistir([
        FFPROBE, "-v", "error",
        "-show_entries", "format=duration",
        "-of", "default=noprint_wrappers=1:nokey=1",
        str(video_yolu),
    ]).stdout.strip()
    try:
        d = float(sure)
    except ValueError:
        return False
    seek = max(0.0, d - 0.05)
    r = _calistir([
        FFMPEG, "-y", "-ss", str(seek), "-i", str(video_yolu),
        "-frames:v", "1", "-q:v", "1",
        str(cikis_resim),
    ])
    return Path(cikis_resim).exists()


def videolari_birlestir(video_listesi: List[str | Path], cikis: str | Path) -> bool:
    cikis = Path(cikis)
    liste_dosya = cikis.parent / "concat_list.txt"
    with open(liste_dosya, "w", encoding="utf-8") as f:
        for v in video_listesi:
            yol = str(v).replace("'", "'\\''")
            f.write(f"file '{yol}'\n")
    r = _calistir([
        FFMPEG, "-y", "-f", "concat", "-safe", "0",
        "-i", str(liste_dosya), "-c", "copy", str(cikis),
    ])
    liste_dosya.unlink(missing_ok=True)
    return cikis.exists()


def videoya_ses_ekle(video: str | Path, ses: str | Path, cikis: str | Path) -> bool:
    r = _calistir([
        FFMPEG, "-y", "-i", str(video), "-i", str(ses),
        "-c:v", "copy", "-c:a", "aac", "-b:a", "192k",
        "-map", "0:v:0", "-map", "1:a:0", "-shortest",
        str(cikis),
    ])
    return Path(cikis).exists()


def ilk_kare_cikar(video_yolu: str | Path, cikis: str | Path) -> bool:
    r = _calistir([
        FFMPEG, "-y", "-i", str(video_yolu),
        "-frames:v", "1", "-q:v", "2",
        str(cikis),
    ])
    return Path(cikis).exists()


def ffmpeg_var_mi() -> bool:
    try:
        r = _calistir([FFMPEG, "-version"])
        return r.returncode == 0
    except FileNotFoundError:
        return False
