import sqlite3
from random import sample

from innertube.clients import InnerTube

client = InnerTube("WEB")
cache = sqlite3.connect("cache.db")
cursor = cache.cursor()


# def recommend(history):
#    recommendations = []
#    for video_id in history:
#        video = client.next(video_id)
#        recommendations += fetch_recommended(video)
#    return recommendations


# data = client.search(query="distrotube")
# video = client.next("BV1O7RR-VoA")


def fetch_recommended(video, verbose=False):
    # we need to fetch all of the recommended videos
    recommended = []

    try:
        recommended.append(
            video["contents"]["twoColumnWatchNextResults"]["autoplay"]["autoplay"][
                "sets"
            ][0]["autoplayVideo"]["watchEndpoint"]["videoId"]
        )
    except:
        if verbose:
            print("ERR:no autoplay (fetch_recommended)")

    try:
        reccount = len(
            video["contents"]["twoColumnWatchNextResults"]["secondaryResults"][
                "secondaryResults"
            ]["results"]
        )

        if verbose:
            print(
                "INFO: Recommendation count is "
                + str(reccount)
                + " (fetch_recommended)"
            )
    except:
        if verbose:
            print("ERR:no recommendations (fetch_recommended)")
    else:
        for rec in video["contents"]["twoColumnWatchNextResults"]["secondaryResults"][
            "secondaryResults"
        ]["results"]:
            if "compactVideoRenderer" in rec:
                recommended.append(rec["compactVideoRenderer"]["videoId"])
            else:
                if verbose:
                    print("WARN:invalid format (fetch_recommended)")

    if len(recommended) == 0:
        recommended.append("")

    return recommended


def fetch_from_database(video_id, verbose=False):
    query = "SELECT vid2 FROM recommends WHERE vid1='" + video_id + "'"
    if verbose:
        print("INFO: querying database: " + query)
    cursor.execute(query)
    response = cursor.fetchall()
    if verbose:
        print("INFO: response was: " + response.__str__())
    formatted_response = []
    for tup in response:
        formatted_response.append(tup[0])
    return formatted_response


def insert_to_database(video_id, recommended):
    pair_insert = []
    for vid in recommended:
        pair_insert.append((video_id, vid))
        # print(pair_insert)
    cursor.executemany(
        "INSERT INTO recommends VALUES(?, ?)",
        pair_insert,
    )
    cache.commit()


def recommend_by_video(video_id, use_cache=True, verbose=False):
    recommended = []
    if use_cache:
        response = fetch_from_database(video_id, verbose=verbose)
        if len(response) == 0:
            recommended_now = fetch_recommended(client.next(video_id), verbose=verbose)
            if len(recommended_now) != 0 and recommended_now[0] != "":
                insert_to_database(video_id, recommended_now)
            recommended = recommended_now
        else:
            recommended = response
    else:
        recommended = fetch_recommended(client.next(video_id), verbose=verbose)
    return recommended


# minp - cuts off all videos that have worse value than `minp`. Set to 0 to disable.
def sampler(history, count, minp: float = 0):
    """Selects `count` random videos from history."""
    videos = []
    for i in range(0, count):
        entry = sample(history, 1)[0]
        if "quality" in entry:
            while entry["quality"] < minp:
                entry = sample(history, 1)[0]
        videos.append(entry)

    return videos


def remove_viewed(history, videos):
    new_videos = videos.copy()
    for entry in history:
        for video in new_videos:
            if entry["videoId"] == video:
                new_videos.remove(video)
    return new_videos


def recommend(history, count=8, verbose=False, use_cache=True):
    recommended = []
    initial_videos = sampler(history, count, minp=0.8)
    for entry in initial_videos:
        video_id = entry["videoId"]
        title = entry["title"]
        if verbose:
            print("INFO:recommending by " + video_id + ': "' + title + '"')
        rec = remove_viewed(
            history, recommend_by_video(video_id, use_cache=use_cache, verbose=verbose)
        )
        if rec[0] != "":
            recommended.append(sample(rec, k=1)[0])

    return recommended


def id_to_link(id_list):
    link_list = []
    for id in id_list:
        link_list.append("https://youtu.be/" + id)
    return link_list
