from __future__ import annotations
import re
from typing import Optional, List
from youtube_transcript_api import YouTubeTranscriptApi, NoTranscriptFound, TranscriptsDisabled
import json as _json
from urllib.request import urlopen as _urlopen
from urllib.parse import quote as _quote
from .common import make_structured

_YT_RE = re.compile(r"(?:v=|youtu\.be/|/shorts/)([A-Za-z0-9_-]{11})")

def _video_id(url_or_id: str) -> Optional[str]:
    if len(url_or_id) == 11 and re.match(r"^[A-Za-z0-9_-]{11}$", url_or_id):
        return url_or_id
    m = _YT_RE.search(url_or_id)
    return m.group(1) if m else None

def _format_transcript(tr: List[dict]) -> str:
    lines = []
    for item in tr:
        start = float(item.get("start", 0.0))
        text = item.get("text","").replace("\n"," ")
        mm = int(start // 60); ss = int(start % 60)
        lines.append(f"[{mm:02d}:{ss:02d}] {text}")
    return "\n".join(lines)

# Prefer instance API; fall back to generated transcript if needed
def _fetch_transcript(vid: str) -> List[dict]:
    langs = ["en","en-US","en-GB"]
    ytt = YouTubeTranscriptApi()
    try:
        return ytt.fetch(vid, languages=langs).to_raw_data()
    except NoTranscriptFound:
        # try auto-generated English transcript
        listing = ytt.list(vid)
        return listing.find_generated_transcript(langs).fetch().to_raw_data()

def _fetch_title(vid: str) -> str | None:
    """Try to pull the video title via YouTube oEmbed (no extra deps)."""
    try:
        oembed_url = f"https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v={_quote(vid)}&format=json"
        with _urlopen(oembed_url, timeout=5) as resp:  # type: ignore
            data = _json.loads(resp.read().decode("utf-8"))
            return data.get("title") if isinstance(data, dict) else None
    except Exception:  # pragma: no cover - network variability
        return None

def ingest_youtube(url_or_id: str, title: str | None = None):
    vid = _video_id(url_or_id) or url_or_id
    # Resolve title if not explicitly provided
    resolved_title = title or _fetch_title(vid) or "YouTube Video"
    try:
        tr = _fetch_transcript(vid)
        text = _format_transcript(tr)
        return make_structured(text, kind="youtube", url=f"https://www.youtube.com/watch?v={vid}", title=resolved_title)
    except (NoTranscriptFound, TranscriptsDisabled, Exception):
        return make_structured(f"[NO TRANSCRIPT AVAILABLE for {vid}]", kind="youtube", url=f"https://www.youtube.com/watch?v={vid}", title=resolved_title)