import argparse
import asyncio
import concurrent.futures
import typing as T

import googletrans

from bubblesub.api import Api
from bubblesub.api.cmd import BaseCommand
from bubblesub.ass.event import Event
from bubblesub.cmd.common import SubtitlesSelection
from bubblesub.opt.menu import MenuCommand, SubMenu


def retry(func: T.Callable, *args: T.Any, **kwargs: T.Any) -> T.Any:
    max_tries = 3
    for i in range(max_tries - 1):
        try:
            return func(*args, **kwargs)
        except Exception as ex:
            pass
    return func(*args, **kwargs)


class GoogleTranslateCommand(BaseCommand):
    names = ["tl", "google-translate"]
    help_text = "Puts results of Google translation into selected subtitles."

    @property
    def is_enabled(self) -> bool:
        return self.args.target.makes_sense

    async def run(self) -> None:
        await asyncio.get_event_loop().run_in_executor(
            None,
            self.run_in_background,
            await self.args.target.get_subtitles(),
        )

    def run_in_background(self, subs: T.List[Event]) -> None:
        with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
            future_to_sub = {
                executor.submit(self.recognize, sub): sub for sub in subs
            }
            completed, non_completed = concurrent.futures.wait(
                future_to_sub, timeout=5
            )

        with self.api.undo.capture():
            for future, sub in future_to_sub.items():
                if future not in completed:
                    continue
                try:
                    result = future.result()
                except Exception as ex:
                    self.api.log.error(f"line #{sub.number}: error ({ex})")
                else:
                    self.api.log.info(f"line #{sub.number}: OK")
                    if sub.text:
                        sub.text += r"\N" + result.text
                    else:
                        sub.text = result.text

        for future, sub in future_to_sub.items():
            if future in non_completed:
                self.api.log.info(f"line #{sub.number}: timeout")

    def recognize(self, sub: Event) -> str:
        self.api.log.info(f"line #{sub.number} - analyzing")
        translator = googletrans.Translator()
        return retry(
            translator.translate,
            sub.note.replace("\\N", "\n"),
            src=self.args.code,
            dest="en",
        )

    @staticmethod
    def decorate_parser(api: Api, parser: argparse.ArgumentParser) -> None:
        parser.add_argument(
            "-t",
            "--target",
            help="subtitles to process",
            type=lambda value: SubtitlesSelection(api, value),
            default="selected",
        )
        parser.add_argument("code", help="language code")


COMMANDS = [GoogleTranslateCommand]
MENU = [
    SubMenu(
        "&Translate",
        [
            MenuCommand("&Japanese", "tl ja"),
            MenuCommand("&German", "tl de"),
            MenuCommand("&French", "tl fr"),
            MenuCommand("&Italian", "tl it"),
            MenuCommand("&Polish", "tl pl"),
            MenuCommand("&Auto", "tl auto"),
        ],
    )
]

@@ -3160,24 +3160,70 @@
 , %22tl pl%22),%0A
+            MenuCommand(%22&Spanish%22, %22tl es%22),%0A
             

add spanish