import os

from dotenv import load_dotenv
from dateutil.parser import parse
from sqlmodel import Session, select, SQLModel, create_engine
import requests

from youtube.models import YouTube

load_dotenv()

YT_CHANNEL = os.environ["YT_CHANNEL"]
YOUTUBE_API_KEY = os.environ["YOUTUBE_API_KEY"]
DATABASE_URL = os.environ["DATABASE_URL"]

YOUTUBE_VIDEO = "youtube#video"
BASE_URL = (
    "https://www.googleapis.com/youtube/v3/search?key={key}"
    "&channelId={channel}&part=snippet,id&order=date&maxResults=20"
)


engine = create_engine(DATABASE_URL, echo=False)


def get_session():
    with Session(engine) as session:
        yield session


def create_db_and_tables():
    SQLModel.metadata.create_all(engine)


def get_videos_from_channel(channel: str = YT_CHANNEL) -> list[dict]:
    base_url = BASE_URL.format(key=YOUTUBE_API_KEY,
                               channel=channel)
    next_page, url = None, base_url
    videos = []
    while True:
        if next_page is not None:
            url = base_url + f"&pageToken={next_page}"

        response = requests.get(url).json()

        for vid in response["items"]:
            if vid["id"]["kind"] != "youtube#video":
                continue
            videos.append(vid)

        if "nextPageToken" not in response:
            break

        next_page = response["nextPageToken"]

    return videos


def insert_youtube_videos(session: Session, videos: list[dict]) -> None:
    num_inserted = 0
    for video in videos:
        video_id = video["id"]["videoId"]
        title = video["snippet"]["title"]
        description = video["snippet"]["description"]
        thumb = video["snippet"]["thumbnails"]["medium"]["url"]
        published = video["snippet"]["publishTime"]

        statement = select(YouTube).where(YouTube.video_id == video_id)
        results = session.exec(statement)
        if results.first() is not None:
            continue

        youtube = YouTube(
            video_id=video_id,
            title=title,
            description=description,
            thumb=thumb,
            published=parse(published),
        )

        session.add(youtube)
        num_inserted += 1

    session.commit()

    statement = select(YouTube)
    results = session.exec(statement)
    total_records = len(results.all())
    print(f"Total records: {total_records} (newly inserted: {num_inserted})")


if __name__ == "__main__":
    create_db_and_tables()
    videos = get_videos_from_channel()
    with Session(engine) as session:
        insert_youtube_videos(session, videos)

dateutil.parser.parse sqlmodel.create_engine sqlmodel.Session sqlmodel.SQLModel.metadata.create_all sqlmodel.select dotenv.load_dotenv requests.get
[((191, 204), 'dotenv.load_dotenv', 'load_dotenv', ([], {}), '()\n', (202, 204), False, 'from dotenv import load_dotenv\n'), ((522, 561), 'sqlmodel.create_engine', 'create_engine', (['DATABASE_URL'], {'echo': '(False)'}), '(DATABASE_URL, echo=False)\n', (535, 561), False, 'from sqlmodel import Session, select, SQLModel, create_engine\n'), ((676, 712), 'sqlmodel.SQLModel.metadata.create_all', 'SQLModel.metadata.create_all', (['engine'], {}), '(engine)\n', (704, 712), False, 'from sqlmodel import Session, select, SQLModel, create_engine\n'), ((2206, 2221), 'sqlmodel.select', 'select', (['YouTube'], {}), '(YouTube)\n', (2212, 2221), False, 'from sqlmodel import Session, select, SQLModel, create_engine\n'), ((592, 607), 'sqlmodel.Session', 'Session', (['engine'], {}), '(engine)\n', (599, 607), False, 'from sqlmodel import Session, select, SQLModel, create_engine\n'), ((2481, 2496), 'sqlmodel.Session', 'Session', (['engine'], {}), '(engine)\n', (2488, 2496), False, 'from sqlmodel import Session, select, SQLModel, create_engine\n'), ((1062, 1079), 'requests.get', 'requests.get', (['url'], {}), '(url)\n', (1074, 1079), False, 'import requests\n'), ((1760, 1775), 'sqlmodel.select', 'select', (['YouTube'], {}), '(YouTube)\n', (1766, 1775), False, 'from sqlmodel import Session, select, SQLModel, create_engine\n'), ((2083, 2099), 'dateutil.parser.parse', 'parse', (['published'], {}), '(published)\n', (2088, 2099), False, 'from dateutil.parser import parse\n')]