"""
download_content.py
Descarga archivos de audio (MP3) y documentos (PDF/ZIP) capturados
en course_content.json a almacenamiento local.

Estructura de destino:
  storage/app/course-media/curso-de-ingles-raio/
    audio/{num:02d}-{filename}.mp3
    docs/{num:02d}-{filename}.pdf
"""
import json
import sys
import re
import urllib.request
from pathlib import Path
from urllib.parse import urlparse

sys.stdout.reconfigure(encoding="utf-8")

SCRIPTS_DIR = Path(__file__).parent
BASE_DIR    = SCRIPTS_DIR.parent
CONTENT_FILE = SCRIPTS_DIR / "course_content.json"

MEDIA_DIR = BASE_DIR / "storage" / "app" / "course-media" / "curso-de-ingles-raio"
AUDIO_DIR = MEDIA_DIR / "audio"
DOCS_DIR  = MEDIA_DIR / "docs"
# Also copy to public/ for web access
PUBLIC_BASE     = BASE_DIR / "public" / "media" / "imported" / "curso-de-ingles-raio"
PUBLIC_AUDIO_DIR = PUBLIC_BASE / "audio"
PUBLIC_DOCS_DIR  = PUBLIC_BASE / "docs"

for d in [AUDIO_DIR, DOCS_DIR, PUBLIC_AUDIO_DIR, PUBLIC_DOCS_DIR]:
    d.mkdir(parents=True, exist_ok=True)


def log(msg, level="INFO"):
    icons = {"INFO": "  ", "OK": "[OK]", "SKIP": "[--]", "ERROR": "[!!]", "HEAD": "\n==="}
    print(f"{icons.get(level,'  ')} {msg}", flush=True)


def safe_filename(url: str, prefix: str) -> str:
    path = urlparse(url).path
    name = Path(path).name or "file"
    # Strip query string artifacts
    name = re.sub(r'[?&=].*$', '', name)
    stem = re.sub(r'[^\w.-]', '-', Path(name).stem)[:60]
    ext  = Path(name).suffix.lower() or ".bin"
    return f"{prefix}-{stem}{ext}"


def download_file(url: str, dest: Path) -> bool:
    if dest.exists() and dest.stat().st_size > 5_000:
        log(f"Ya existe ({dest.stat().st_size // 1000}kB): {dest.name}", "SKIP")
        return True
    try:
        req = urllib.request.Request(url, headers={
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
        })
        with urllib.request.urlopen(req, timeout=60) as resp:
            data = resp.read()
        if len(data) < 1000:
            log(f"Respuesta demasiado pequeña ({len(data)} bytes): {url[:60]}", "ERROR")
            return False
        dest.write_bytes(data)
        log(f"OK ({len(data) // 1000}kB): {dest.name}", "OK")
        return True
    except Exception as e:
        log(f"Error: {e} — {url[:70]}", "ERROR")
        return False


def main():
    if not CONTENT_FILE.exists():
        log(f"No encontre {CONTENT_FILE}. Ejecuta primero scrape_content.py", "ERROR")
        sys.exit(1)

    lessons = json.loads(CONTENT_FILE.read_text(encoding="utf-8"))
    log(f"RAIO Content Downloader — {len(lessons)} lecciones", "HEAD")

    audio_ok = audio_fail = 0
    doc_ok   = doc_fail   = 0

    for lesson in lessons:
        num = lesson["num"]
        prefix = f"{num:02d}"

        # --- Audio ---
        for audio in lesson.get("audio_urls", []):
            url = audio.get("url", "")
            if not url or not url.startswith("http"):
                continue
            fname = safe_filename(url, prefix)
            dest  = AUDIO_DIR / fname
            pub   = PUBLIC_AUDIO_DIR / fname
            ok    = download_file(url, dest)
            if ok:
                audio_ok += 1
                # Copy/link to public/ for MediaController audio route
                if not pub.exists():
                    try:
                        import shutil
                        shutil.copy2(dest, pub)
                    except Exception:
                        pass
                # Update the URL in-place to local route path
                audio["local_path"] = f"media/imported/curso-de-ingles-raio/audio/{fname}"
            else:
                audio_fail += 1

        # --- Documents ---
        for doc in lesson.get("doc_urls", []):
            url = doc.get("url", "")
            if not url or not url.startswith("http"):
                continue
            fname = safe_filename(url, prefix)
            dest  = DOCS_DIR / fname
            pub   = PUBLIC_DOCS_DIR / fname
            ok    = download_file(url, dest)
            if ok:
                doc_ok += 1
                # Copy to public/ for browser download
                if not pub.exists():
                    try:
                        import shutil
                        shutil.copy2(dest, pub)
                    except Exception:
                        pass
                # Use forward slashes so URL works in browser
                doc["local_path"] = f"media/imported/curso-de-ingles-raio/docs/{fname}"
            else:
                doc_fail += 1

    # Save updated content with local_path fields
    CONTENT_FILE.write_text(
        json.dumps(lessons, ensure_ascii=False, indent=2),
        encoding="utf-8"
    )

    log(f"Audio: {audio_ok} OK / {audio_fail} fallidos", "OK")
    log(f"Docs:  {doc_ok} OK / {doc_fail} fallidos", "OK")
    log(f"course_content.json actualizado con local_path", "OK")


if __name__ == "__main__":
    main()
