"""Upload a rendered Short using YouTube Data API OAuth.

One-time setup:
1. Create a Desktop OAuth client in Google Cloud with YouTube Data API v3 enabled.
2. Put the downloaded JSON at credentials/client_secret.json.
3. Run: python3 upload.py output/VIDEO.mp4 stories/STORY.json --privacy private

The first run opens a browser consent screen and saves credentials/token.json.
"""
import argparse
import json
import sys
from pathlib import Path

from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload

BASE_DIR = Path(__file__).parent
CREDENTIALS_DIR = BASE_DIR / "credentials"
CLIENT_SECRET = CREDENTIALS_DIR / "client_secret.json"
TOKEN = CREDENTIALS_DIR / "token.json"
SCOPES = ["https://www.googleapis.com/auth/youtube.upload"]


def youtube_client():
    creds = None
    if TOKEN.exists():
        creds = Credentials.from_authorized_user_file(TOKEN, SCOPES)
    if creds and creds.expired and creds.refresh_token:
        creds.refresh(Request())
    if not creds or not creds.valid:
        if not CLIENT_SECRET.exists():
            raise FileNotFoundError(
                f"Missing {CLIENT_SECRET}. Download a Desktop OAuth client JSON from Google Cloud."
            )
        flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRET, SCOPES)
        creds = flow.run_local_server(port=0)
    CREDENTIALS_DIR.mkdir(exist_ok=True)
    TOKEN.write_text(creds.to_json())
    return build("youtube", "v3", credentials=creds)


def upload(video: Path, story: dict, privacy: str) -> str:
    tags = [tag.lstrip("#") for tag in story.get("hashtags", [])]
    body = {
        "snippet": {
            "title": story["title"][:100],
            "description": story.get("description", "")[:5000],
            "tags": tags,
            "categoryId": "24",  # Entertainment
        },
        "status": {
            "privacyStatus": privacy,
            "selfDeclaredMadeForKids": False,
        },
    }
    request = youtube_client().videos().insert(
        part="snippet,status",
        body=body,
        media_body=MediaFileUpload(str(video), chunksize=-1, resumable=True),
    )
    response = None
    while response is None:
        _, response = request.next_chunk()
    return f"https://www.youtube.com/watch?v={response['id']}"


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Upload a rendered YouTube Short")
    parser.add_argument("video", type=Path)
    parser.add_argument("story", type=Path)
    parser.add_argument("--privacy", choices=["private", "unlisted", "public"], default="private")
    args = parser.parse_args()
    if not args.video.exists() or not args.story.exists():
        parser.error("Video and story JSON must both exist")
    try:
        url = upload(args.video, json.loads(args.story.read_text()), args.privacy)
        print(url)
    except Exception as exc:
        print(f"Upload failed: {exc}", file=sys.stderr)
        sys.exit(1)
