#!/usr/bin/env python3
"""
Anime Downloader
=============================

Небольшая ЛЕГАЛЬНАЯ обёртка над yt-dlp для скачивания видео по ССЫЛКАМ,
которые вы предоставляете сами. Инструмент НЕ парсит и НЕ обходит защиту
пиратских сайтов — он лишь передаёт URL в yt-dlp, который поддерживает
тысячи легальных площадок (YouTube, официальные каналы студий и т.д.).

Пользователь сам отвечает за соблюдение авторских прав и условий площадок.

Использование:
    python anime_downloader.py URL [URL2 ...] [-o DIR] [-q QUALITY]
    python anime_downloader.py --batch links.txt -o downloads -q 720
"""
from __future__ import annotations

import argparse
import shutil
import subprocess
import sys
from pathlib import Path

BANNER = r"""
  ______    _ _ _        _                _
 |  ____|  | (_) |      ( )              (_)
 | |__   __| |_| | __ _ |/ ___     __ _  _ ___
 |  __| / _` | | |/ _` |  / __|   / _` || / _ \
 | |___| (_| | | | (_| |  \__ \  | (_| || |  __/
 |______\__,_|_|_|\__,_|  |___/   \__,_||_|\___|
        Anime Downloader — legal yt-dlp wrapper
"""


def check_ytdlp() -> str:
    exe = shutil.which("yt-dlp")
    if exe:
        return exe
    try:
        import yt_dlp  # noqa: F401
        return sys.executable + " -m yt_dlp"
    except ImportError:
        sys.exit(
            "[anime-dl] yt-dlp не найден. Установи: pip install -r requirements.txt\n"
            "       или: pip install -U yt-dlp"
        )


def quality_format(q: str | None) -> str:
    if not q:
        return "bestvideo*+bestaudio/best"
    q = q.lower().rstrip("p")
    if not q.isdigit():
        return "bestvideo*+bestaudio/best"
    h = int(q)
    return f"bestvideo[height<={h}]+bestaudio/best[height<={h}]/best"


def download(urls: list[str], out_dir: Path, quality: str | None) -> int:
    exe = check_ytdlp()
    out_dir.mkdir(parents=True, exist_ok=True)
    template = str(out_dir / "%(title).150B [%(id)s].%(ext)s")
    cmd = exe.split() + [
        "-f", quality_format(quality),
        "--merge-output-format", "mp4",
        "-o", template,
        "--no-overwrites", "--continue",
        "--embed-metadata", "--embed-subs",
        "--sub-langs", "en,ru,ja",
        *urls,
    ]
    print(f"[anime-dl] Скачиваю {len(urls)} ссылок в {out_dir}/ (quality={quality or 'best'})")
    try:
        return subprocess.call(cmd)
    except FileNotFoundError:
        sys.exit("[anime-dl] Не удалось запустить yt-dlp.")
    except KeyboardInterrupt:
        print("\n[anime-dl] Прервано пользователем.")
        return 130


def read_batch(path: Path) -> list[str]:
    if not path.exists():
        sys.exit(f"[anime-dl] Файл со ссылками не найден: {path}")
    urls = []
    for line in path.read_text(encoding="utf-8").splitlines():
        line = line.strip()
        if line and not line.startswith("#"):
            urls.append(line)
    return urls


def main() -> None:
    parser = argparse.ArgumentParser(
        description="Anime Downloader — легальная обёртка над yt-dlp.")
    parser.add_argument("urls", nargs="*", help="Одна или несколько ссылок на видео.")
    parser.add_argument("--batch", type=Path, help="Файл со списком ссылок.")
    parser.add_argument("-o", "--output", type=Path, default=Path("downloads"),
                        help="Папка для загрузок (по умолчанию: downloads).")
    parser.add_argument("-q", "--quality", help="Макс. высота, напр. 720 или 1080.")
    parser.add_argument("--no-banner", action="store_true")
    args = parser.parse_args()

    if not args.no_banner:
        print(BANNER)

    urls = list(args.urls)
    if args.batch:
        urls += read_batch(args.batch)
    if not urls:
        parser.print_help()
        sys.exit("\n[anime-dl] Не задано ни одной ссылки.")

    code = download(urls, args.output, args.quality)
    print("[anime-dl] Готово. Приятного просмотра! 🍜" if code == 0 else f"[anime-dl] Код {code}.")
    sys.exit(code)


if __name__ == "__main__":
    main()
