import requests
from bs4 import BeautifulSoup
from youtube_transcript_api import YouTubeTranscriptApi

from .util import YoutubeData


class YoutubeUtil:
    @staticmethod
    def get_youtube_data(target_source: str) -> (str, bool, str):
        transcript = title = description = ts_transcript_list = None
        try:
            title, description = YoutubeUtil.get_video_info(target_source)
            transcript, ts_transcript_list = YoutubeUtil.convert_youtube_transcript(target_source)
        except Exception as e:
            return YoutubeData(transcript, title, description, ts_transcript_list), False, str(e)
        return YoutubeData(transcript, title, description, ts_transcript_list), True, ""

    @staticmethod
    def get_video_info(target_source):
        url = f"https://www.youtube.com/watch?v={target_source}"
        response = requests.get(url)

        if response.status_code != 200:
            return None

        soup = BeautifulSoup(response.content, "html.parser")

        title = soup.find("meta", itemprop="name")["content"]
        description = soup.find("meta", itemprop="description")["content"]

        return title, description

    @staticmethod
    def convert_youtube_transcript(target_source) -> (str, list):
        def extract_video_id_from_url(url):
            return url.split("v=")[1]

        def is_url(url):
            return "youtube.com" in url

        def merge_transcript(transcript):
            ts_transcript_list = []

            current_start = transcript[0]['start']
            current_text = transcript[0]['text']
            for i in range(1, len(transcript)):
                if transcript[i]['start'] - current_start >= 30:
                    ts_transcript_list.append({'text': current_text, 'start': current_start})
                    current_start = transcript[i]['start']
                    current_text = transcript[i]['text']
                else:
                    current_text += ' ' + transcript[i]['text']

            ts_transcript_list.append({'text': current_text, 'start': current_start})
            return ts_transcript_list

        if is_url(target_source):
            video_id = extract_video_id_from_url(target_source)
        else:
            video_id = target_source

        preferred_lang = ['en', 'zh', 'zh-Hans', 'zh-Hant', 'ja', 'it', 'de', 'fr']
        try:
            transcript = YouTubeTranscriptApi.get_transcript(video_id, preferred_lang)
        except Exception as e:
            import youtube_transcript_api
            if isinstance(e, youtube_transcript_api._errors.TranscriptsDisabled):
                raise Exception(e)
            transcript_list = YouTubeTranscriptApi.list_transcripts(video_id)
            transcript = transcript_list.find_generated_transcript(preferred_lang)
        text = " ".join([entry['text'] for entry in transcript])
        merged_transcript = merge_transcript(transcript)

        return text, merged_transcript


if __name__ == '__main__':
    target_source = 'lSTEhG021Jc'
    youtube_data, is_success, error_msg = YoutubeUtil.get_youtube_data(target_source)
    youtube_data: YoutubeData
    print(youtube_data.title)
    print(youtube_data.description)
    print(youtube_data.shorten_transcript)

    print("Transcript with timestamp:")
    # for entry in youtube_data.ts_transcript_list:
    #     print(f"{int(entry['start'] // 60)}:{int(entry['start'] % 60):02d} {entry['text'][:50]}")
    for entry in youtube_data.ts_transcript_list:
        print(f"{int(entry['start'] // 60)}:{int(entry['start'] % 60):02d} {entry['text']}")
