import os
import requests
from pathlib import Path
from rich.console import Console
from rich.progress import Progress, SpinnerColumn, TextColumn, BarColumn
from .api_client import (
    fetch_tiktok,
    fetch_facebook,
    fetch_instagram,
    fetch_youtube_mp4,
    fetch_youtube_mp3,
)
from .utils import validate_url, sanitize_filename

console = Console()

# ────────────────────────
# UTILS: FOLDER DOWNLOAD
# ────────────────────────

def get_default_download_dir() -> Path:
    """Return the system's default Downloads directory."""
    home = Path.home()
    if os.name == "nt":  # Windows
        import winreg
        try:
            with winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders") as key:
                downloads_path = winreg.QueryValueEx(key, "{374DE290-123F-4565-9164-39C4925E467B}")[0]
                return Path(downloads_path)
        except Exception:
            pass
        return home / "Downloads"
    else:  # macOS, Linux
        return home / "Downloads"

def get_output_path(filename: str) -> Path:
    """Return full path in ~/Downloads/medsos-downloader/, avoiding duplicates."""
    download_dir = get_default_download_dir() / "medsos-downloader"
    download_dir.mkdir(parents=True, exist_ok=True)
    full_path = download_dir / filename

    counter = 1
    original_path = full_path
    while full_path.exists():
        name, ext = original_path.stem, original_path.suffix
        full_path = download_dir / f"{name}_{counter}{ext}"
        counter += 1

    return full_path

def _download_file(url: str, output_path: Path, title: str = "File"):
    console.print(f"▶️ Mengunduh: {output_path.name}")

    headers = {
        "User-Agent": (
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
            "AppleWebKit/537.36 (KHTML, like Gecko) "
            "Chrome/122.0.0.0 Safari/537.36"
        ),
        "Accept": "*/*",
        "Accept-Encoding": "identity",
        "Connection": "keep-alive",
    }

    with requests.get(
        url,
        headers=headers,
        stream=True,
        allow_redirects=True,
        timeout=60
    ) as r:
        r.raise_for_status()
        total_size = int(r.headers.get("content-length", 0))

        with Progress(
            SpinnerColumn(),
            TextColumn("[progress.description]{task.description}"),
            BarColumn(),
            TextColumn("{task.completed}/{task.total} bytes"),
        ) as progress:
            task = progress.add_task(
                "Mengunduh...",
                total=total_size if total_size > 0 else None
            )

            with open(output_path, "wb") as f:
                for chunk in r.iter_content(chunk_size=1024 * 1024):
                    if chunk:
                        f.write(chunk)
                        if total_size > 0:
                            progress.update(task, advance=len(chunk))

    console.print(f"📁 Tersimpan di: {output_path}")

# ────────────────────────
# PLATFORM HANDLERS
# ────────────────────────

def download_media(url: str, platform: str = "tiktok"):
    """Main dispatcher based on platform."""
    if platform == "tiktok":
        _download_tiktok(url)
    elif platform == "instagram":
        _download_instagram(url)
    elif platform == "facebook":
        _download_facebook(url)
    elif platform == "youtube-mp4":
        _download_youtube_mp4(url)
    elif platform == "youtube-mp3":
        _download_youtube_mp3(url)
    else:
        raise ValueError(f"Platform tidak didukung: {platform}")

# ─── TIKTOK ───────────────────────────────────────────────

def _download_tiktok(url: str):
    if not validate_url(url, "tiktok"):
        raise ValueError("URL bukan dari TikTok.")
    console.print("🔍 Mengambil data TikTok...")
    data = fetch_tiktok(url)
    if not data.get("status"):
        raise Exception(data.get("message", "Gagal dari API TikTok."))
    
    result = data["result"]
    title = result.get("title", "untitled")
    author = result.get("author", {}).get("nickname", "unknown")
    video_url = result.get("video_nowm") or result.get("video_wm")
    if not video_url:
        raise Exception("Tidak ada URL video ditemukan.")
    
    safe_name = sanitize_filename(f"{author}_{title}")
    output_path = get_output_path(f"{safe_name}.mp4")
    _download_file(video_url, output_path, "video TikTok")
    console.print("✅ Unduhan TikTok selesai!")

# ─── INSTAGRAM ────────────────────────────────────────────

def _download_instagram(url: str):
    if not validate_url(url, "instagram"):
        raise ValueError("URL bukan dari Instagram.")
    console.print("🔍 Mengambil data Instagram...")
    data = fetch_instagram(url)
    if not data.get("status"):
        raise Exception(data.get("message", "Gagal dari API Instagram."))
    
    result = data["result"]
    username = result.get("username", "unknown")
    media_type = result.get("type", "unknown")  # "video" atau "image"
    
    if media_type == "video":
        video_url = result.get("video_url")
        if not video_url:
            raise Exception("Tidak ada video ditemukan.")
        safe_name = sanitize_filename(f"{username}_instagram_video")
        output_path = get_output_path(f"{safe_name}.mp4")
        _download_file(video_url, output_path, "video Instagram")
    elif media_type == "image":
        images = result.get("images", [])
        if not images:
            raise Exception("Tidak ada gambar ditemukan.")
        # Download gambar pertama (bisa dikembangkan jadi semua)
        image_url = images[0]
        safe_name = sanitize_filename(f"{username}_instagram_photo")
        output_path = get_output_path(f"{safe_name}.jpg")
        _download_file(image_url, output_path, "foto Instagram")
    else:
        raise Exception(f"Tipe media tidak didukung: {media_type}")
    
    console.print("✅ Unduhan Instagram selesai!")

# ─── FACEBOOK ─────────────────────────────────────────────

def _download_facebook(url: str, quality: str = "hd"):
    """
    Download video Facebook dengan pilihan kualitas.
    
    quality:
      - "hd" (default)
      - "sd"
    """

    if not validate_url(url, "facebook"):
        raise ValueError("URL bukan dari Facebook.")

    quality = quality.lower()
    if quality not in ("hd", "sd"):
        raise ValueError("Quality harus 'hd' atau 'sd'.")

    console.print("🔍 Mengambil data Facebook...")
    data = fetch_facebook(url)

    if not data.get("status"):
        raise Exception(data.get("message", "Gagal dari API Facebook."))

    result = data.get("result", {})

    hd_url = result.get("hd")
    sd_url = result.get("sd")

    if not hd_url and not sd_url:
        raise Exception("Tidak ada video Facebook tersedia.")

    # Pilih URL sesuai parameter, fallback otomatis
    if quality == "hd" and hd_url:
        video_url = hd_url
        final_quality = "HD"
    elif quality == "sd" and sd_url:
        video_url = sd_url
        final_quality = "SD"
    elif hd_url:
        video_url = hd_url
        final_quality = "HD"
    else:
        video_url = sd_url
        final_quality = "SD"

    output_path = get_output_path(f"facebook_{final_quality.lower()}.mp4")

    _download_file(video_url, output_path, f"video Facebook {final_quality}")

    console.print(f"✅ Unduhan Facebook ({final_quality}) selesai!")

# ─── YOUTUBE MP4 ──────────────────────────────────────────

def _download_youtube_mp4(url: str):
    if not validate_url(url, "youtube"):
        raise ValueError("URL bukan dari YouTube.")
    console.print("🔍 Mengambil data YouTube (MP4)...")
    data = fetch_youtube_mp4(url)
    if not data.get("status"):
        raise Exception(data.get("message", "Gagal dari API YouTube MP4."))
    
    result = data["result"]
    download_url = result.get("download_url")
    if not download_url:
        raise Exception("Tidak ada URL unduhan MP4 ditemukan.")
    
    safe_name = sanitize_filename("youtube_video")
    output_path = get_output_path(f"{safe_name}.mp4")
    _download_file(download_url, output_path, "video YouTube (MP4)")
    console.print("✅ Unduhan YouTube MP4 selesai!")

# ─── YOUTUBE MP3 ──────────────────────────────────────────

def _download_youtube_mp3(url: str):
    if not validate_url(url, "youtube"):
        raise ValueError("URL bukan dari YouTube.")
    console.print("🔍 Mengambil data YouTube (MP3)...")
    data = fetch_youtube_mp3(url)
    if not data.get("status"):
        raise Exception(data.get("message", "Gagal dari API YouTube MP3."))
    
    result = data["result"]
    mp3_url = result.get("mp3")
    title = result.get("title", "unknown")
    if not mp3_url:
        raise Exception("Tidak ada URL MP3 ditemukan.")
    
    safe_name = sanitize_filename(f"yt_{title}")
    output_path = get_output_path(f"{safe_name}.mp3")
    _download_file(mp3_url, output_path, "audio YouTube (MP3)")
    console.print("✅ Unduhan YouTube MP3 selesai!")