import argparse
import tempfile

import colorama
from colorama import Fore

from youtube_clipper.downloader import DownloaderLoggingLevel, SubtitlesDownloader
from youtube_clipper.searcher import DeduplicationMode, SubtitlesSearcher
from youtube_clipper.utils import get_available_formats, get_url_from_filename


def main() -> None:
    parser = argparse.ArgumentParser('youtube-clipper', description='YouTube Clipper - tool for finding youtube clips')
    parser.add_argument(
        '--url',
        required=True,
        help='can be any youtube URL supported by yt-dlp: a video, a channel, a playlist, etc; '
             'in case of multiple videos in the output, search will be performed for each video separately',
    )
    parser.add_argument('--query', required=True, help='query to search for')

    yt_dlp_args = parser.add_argument_group('yt-dlp arguments')
    yt_dlp_args.add_argument('--formats', nargs='*', help='subtitles formats to download')
    yt_dlp_args.add_argument('--language', default='en', help='subtitles language')
    yt_dlp_args.add_argument('--subs-dir', required=False, help='if specified, subs will be saved to a provided dir')
    yt_dlp_args.add_argument(
        '--allow-autogenerated', action='store_true', help='whether to allow downloading autogenerated subs'
    )
    yt_dlp_args.add_argument(
        '--logging-level', default='disabled', type=DownloaderLoggingLevel, help='logging level for yt-dlp'
    )

    searcher_args = parser.add_argument_group('searcher arguments')
    searcher_args.add_argument(
        '--show-scores',
        action='store_true',
        help='if set, will show a search score next to a link',
    )
    searcher_args.add_argument('--search-limit', required=False, type=int, help='limit for search results per video')
    searcher_args.add_argument(
        '--enable-pairwise-group',
        action='store_true',
        help='if set, will merge successive overlapping subtitle pairs into one',
    )
    searcher_args.add_argument(
        '--deduplication-mode',
        default='keep_first',
        type=DeduplicationMode,
        help='deduplication mode for consecutive subtitle matches',
    )

    args = parser.parse_args()
    colorama.init(autoreset=True)

    if args.allow_autogenerated is False and args.enable_pairwise_group is False:
        print(Fore.YELLOW + 'Warning: pairwise grouping is disabled on manual subtitles, search might be inaccurate. '
                            'Consider enabling the pairwise grouping with the --enable-pairwise-group option. '
                            'For more details, check README.md')
    available_formats = get_available_formats()
    formats = args.formats or available_formats
    unsupported_formats = set(formats) - set(available_formats)
    if unsupported_formats:
        print(Fore.YELLOW + 'Warning: some of provided formats aren\'t supported:', *unsupported_formats)

    with tempfile.TemporaryDirectory() as tempdir:
        subs_dir = args.subs_dir or tempdir
        downloader = SubtitlesDownloader(
            language=args.language,
            formats=formats,
            allow_autogenerated=args.allow_autogenerated,
            output_dir=subs_dir,
            logging_level=args.logging_level,
        )

        for filename in downloader.get_subtitles(args.url):
            video_url = get_url_from_filename(filename)
            print(Fore.YELLOW + f'Searching for `{args.query}` in {video_url}')

            searcher = SubtitlesSearcher(
                index_directory=tempdir,
                limit=args.search_limit,
                enable_pairwise_group=args.enable_pairwise_group,
                deduplication_mode=args.deduplication_mode,
            )
            searcher.add_subtitles(filename)
            results = searcher.search(args.query)
            if not results:
                print(Fore.RED + f'`{args.query}` wasn\'t found in {video_url}')
                if args.allow_autogenerated and not args.enable_pairwise_group:
                    print(Fore.YELLOW + 'Pairwise grouping was disabled for this search, consider enabling it '
                                        'with the --enable-pairwise-group option. For more details, check README.md')
            else:
                print(Fore.GREEN + f'Found {len(results)} (approximate) occurrence(s) of `{args.query}` in {video_url}')
                for result in results:
                    score_str = Fore.RESET + f'(score: {result.score})' if args.show_scores else ''
                    print(Fore.GREEN + f'{video_url}&t={int(result.offset)}s {score_str}')


if __name__ == '__main__':
    main()
