"""YouTube Data API v3 — 채널별 신규 영상 감지"""

from datetime import datetime, timezone

import requests

YOUTUBE_API_BASE = "https://www.googleapis.com/youtube/v3"


def get_uploads_playlist_id(channel_id: str, api_key: str) -> str | None:
    """채널의 uploads playlist ID를 조회"""
    resp = requests.get(
        f"{YOUTUBE_API_BASE}/channels",
        params={
            "part": "contentDetails",
            "id": channel_id,
            "key": api_key,
        },
    )
    resp.raise_for_status()
    items = resp.json().get("items", [])
    if not items:
        return None
    return items[0]["contentDetails"]["relatedPlaylists"]["uploads"]


def get_new_videos(
    uploads_playlist_id: str,
    last_crawled_at: datetime,
    api_key: str,
) -> list[dict]:
    """uploads playlist에서 last_crawled_at 이후 신규 영상 목록"""
    resp = requests.get(
        f"{YOUTUBE_API_BASE}/playlistItems",
        params={
            "part": "snippet",
            "playlistId": uploads_playlist_id,
            "maxResults": 20,
            "key": api_key,
        },
    )
    resp.raise_for_status()
    items = resp.json().get("items", [])

    # last_crawled_at이 timezone-naive이면 UTC로 보정
    if last_crawled_at.tzinfo is None:
        last_crawled_at = last_crawled_at.replace(tzinfo=timezone.utc)

    new_videos: list[dict] = []
    for item in items:
        snippet = item.get("snippet", {})
        published_at_str = snippet.get("publishedAt", "")
        if not published_at_str:
            continue
        published_at = datetime.fromisoformat(published_at_str.replace("Z", "+00:00"))
        if published_at > last_crawled_at:
            new_videos.append(
                {
                    "video_id": snippet.get("resourceId", {}).get("videoId"),
                    "title": snippet.get("title", "(제목 없음)"),
                    "published_at": published_at_str,
                    "description": snippet.get("description", "")[:1000],
                }
            )
    return new_videos


def get_video_duration(video_id: str, api_key: str) -> str:
    """영상 길이(ISO 8601 duration) 조회"""
    resp = requests.get(
        f"{YOUTUBE_API_BASE}/videos",
        params={
            "part": "contentDetails",
            "id": video_id,
            "key": api_key,
        },
    )
    resp.raise_for_status()
    items = resp.json().get("items", [])
    if not items:
        return "PT0S"
    return items[0]["contentDetails"]["duration"]


def get_active_channels(db) -> list[dict]:  # type: ignore[no-untyped-def]
    """Firestore youtube_channels에서 isActive==True인 채널 로드"""
    docs = db.collection("youtube_channels").where("isActive", "==", True).stream()
    channels: list[dict] = []
    for doc in docs:
        data = doc.to_dict()
        data["_doc_id"] = doc.id
        channels.append(data)
    return channels


def update_last_crawled(db, channel_doc_id: str) -> None:  # type: ignore[no-untyped-def]
    """채널의 lastCrawledAt 필드를 현재 UTC 시각으로 갱신"""
    from google.cloud import firestore  # type: ignore[import-untyped]

    db.collection("youtube_channels").document(channel_doc_id).update(
        {"lastCrawledAt": firestore.SERVER_TIMESTAMP}
    )
