"""
video_bg.py — Pexels API → скачать видео-клип для фона

Если Pexels не доступен → генерируем чёрный видео-файл.
"""

import os
import subprocess
import requests
from pathlib import Path
from dotenv import load_dotenv

load_dotenv(os.path.expanduser("~/.openclaw/.env"))

import shutil
FFMPEG = os.environ.get("FFMPEG_BIN") or shutil.which("ffmpeg") or os.path.expanduser("~/bin/ffmpeg")
FFPROBE = os.environ.get("FFPROBE_BIN") or shutil.which("ffprobe") or FFMPEG  # fallback to ffmpeg


def search_pexels(query: str, per_page: int = 3) -> list[dict]:
    """Поиск видео на Pexels. Возвращает список видео-объектов."""
    api_key = os.environ.get("PEXELS_API_KEY", "")
    if not api_key:
        print("[video_bg] PEXELS_API_KEY не задан, пропускаем поиск.")
        return []

    url = "https://api.pexels.com/videos/search"
    params = {
        "query": query,
        "per_page": per_page,
        "orientation": "landscape",
        "size": "medium",
    }
    headers = {"Authorization": api_key}

    try:
        resp = requests.get(url, params=params, headers=headers, timeout=15)
        resp.raise_for_status()
        data = resp.json()
    except Exception as e:
        print(f"[video_bg] Ошибка Pexels API: {e}")
        return []

    return data.get("videos", [])


def pick_video(video_list: list[dict]) -> str | None:
    """Выбрать URL лучшего видео (предпочитаем 720p, берём любое доступное)."""
    for v in video_list:
        files = v.get("video_files", [])
        # Сначала ищем 720p (1280x720)
        for f in files:
            if f.get("width") == 1280:
                return f.get("link") or f.get("file")
        # Потом любое HD ≥ 1280
        for f in sorted(files, key=lambda x: x.get("width", 0)):
            if f.get("width", 0) >= 1280:
                return f.get("link") or f.get("file")
        # Любое что есть
        if files:
            return files[0].get("link") or files[0].get("file")
    return None


def download_url(url: str, dest: str) -> str:
    """Скачать файл по URL в dest."""
    print(f"[video_bg] Скачиваем {url[:80]}…")
    resp = requests.get(url, stream=True, timeout=60)
    resp.raise_for_status()
    with open(dest, "wb") as f:
        for chunk in resp.iter_content(chunk_size=8192):
            f.write(chunk)
    return dest


def get_duration(path: str) -> float:
    """Длительность видео в секундах через ffmpeg -i."""
    result = subprocess.run(
        [FFMPEG, "-i", path],
        capture_output=True, text=True
    )
    import re
    m = re.search(r"Duration: (\d+):(\d+):([\d.]+)", result.stderr)
    if m:
        h, mn, s = m.groups()
        return int(h) * 3600 + int(mn) * 60 + float(s)
    raise RuntimeError(f"Не удалось получить длительность: {path}")


def create_black_video(duration: float, dest: str, width: int = 1280, height: int = 720):
    """Создать чёрное видео заданной длительности."""
    print(f"[video_bg] Создаём чёрный фон {duration:.1f}s…")
    cmd = [
        FFMPEG, "-f", "lavfi", "-i", f"color=c=black:s={width}x{height}:r=30:d={duration}",
        "-c:v", "libx264", "-pix_fmt", "yuv420p", "-y", dest
    ]
    subprocess.run(cmd, check=True, capture_output=True)
    return dest


def loop_video(source: str, target_duration: float, dest: str):
    """Зациклить видео до нужной длительности."""
    src_dur = get_duration(source)
    if src_dur >= target_duration:
        # Обрезать лишнее
        cmd = [
            FFMPEG, "-i", source, "-t", str(target_duration),
            "-c:v", "libx264", "-pix_fmt", "yuv420p", "-an", "-y", dest
        ]
    else:
        # Зациклить через stream_loop
        loops = int(target_duration / src_dur) + 1
        cmd = [
            FFMPEG, "-stream_loop", str(loops - 1), "-i", source,
            "-t", str(target_duration),
            "-c:v", "libx264", "-pix_fmt", "yuv420p", "-an", "-y", dest
        ]
    subprocess.run(cmd, check=True, capture_output=True)
    return dest


def get_bg_video(search_query: str, audio_duration: float,
                 output_dir: str) -> str:
    """
    Основной entry point.

    1. Ищет видео на Pexels по query
    2. Скачивает и зацикливает до audio_duration
    3. Если Pexels недоступен — создаёт чёрный фон

    Возвращает путь к видео-файлу.
    """
    os.makedirs(output_dir, exist_ok=True)

    raw_path = os.path.join(output_dir, "raw_bg.mp4")
    bg_path  = os.path.join(output_dir, "background.mp4")

    videos = search_pexels(search_query)
    url = pick_video(videos)

    if url:
        try:
            download_url(url, raw_path)
            loop_video(raw_path, audio_duration, bg_path)
            print(f"[video_bg] Видео-фон готов: {bg_path}")
            return bg_path
        except Exception as e:
            print(f"[video_bg] Ошибка скачивания: {e}")

    # Fallback: чёрный фон
    create_black_video(audio_duration, bg_path)
    return bg_path
