from tko.settings.rep_paths import RepPaths
from tko.settings.rep_source import RepSource
from tko.settings.repository import Repository
from tko.settings.settings import Settings
from tko.util.text import Text
from pathlib import Path

class RepSourceActions:
    def __init__(self, folder: Path | None):
        # if folder is set, use folder, else use remote if remote, else .
        if folder is not None:
            folder = Path(folder).resolve()
        else:
            folder = Path.cwd()

        path = RepPaths.rec_search_for_repo_parents(folder)
        if path is None:
            raise ValueError(f"Repositório não encontrado em {folder}")
        self.folder = folder
        self.repo = Repository(path).load_config()
    
    def remote_ls(self):
        rep = self.repo
        sources = rep.data.get_sources()
        print("Você também pode configurar as fontes e filtros manualmente editando o arquivo:")
        print(Text.format("{y}", rep.paths.get_config_file()))
        if len(sources) == 0:
            print("Nenhuma fonte configurada")
            return
        print("Fontes configuradas:")
        for source in sources:
            print(Text.format("- Rótulo: {y}", source.name))
            print(Text.format("  - Link ou Caminho: {y}", source.get_url_link()))
            print(Text.format("  - File Path     : {y}", source.get_source_readme()))
            print(Text.format("  - Filtragem      : {y}", "Desativado" if source.quests is None else 'Ativado'))
            for f in source.quests or []:
                print(f"    - {f}")

    def remote_rm(self, alias: str) -> None:
        rep = self.repo
        sources = rep.data.get_sources()
        found = False
        for source in sources:
            if source.name == alias:
                found = True
                rep.data.del_source(alias)
                print(Text.format("Fonte {y} removida com sucesso.", alias))
                break
        if not found:
            raise Warning("fail: fonte não encontrada.")
        rep.save_config()

    def remote_filter(self, alias: str, quests: list[str] | None = None, tasks: list[str] | None = None, clear: bool = False) -> None:
        rep = self.repo
        sources = rep.data.get_sources()
        found = False
        for source in sources:
            if source.name == alias:
                found = True
                if quests is not None:
                    if source.quests is None:
                        source.quests = []
                    for f in quests:
                        if f not in source.quests:
                            source.quests.append(f)
                if tasks is not None:
                    if source.tasks is None:
                        source.tasks = []
                    for f in tasks:
                        if f not in source.tasks:
                            source.tasks.append(f)
                if clear:
                    source.quests = None
                    source.tasks = None
                print(Text.format("Filtros {y} atualizados com sucesso.", alias))
                break
        if not found:
            raise Warning("fail: fonte não encontrada.")
        rep.save_config()

    def remote_add(self, name: str, remote_default: str | None, remote_url: str | None, remote_dir: str | None, quest_filter: list[str] | None, task_filter: list[str] | None, writeable: bool, branch: str = "master") -> None:
        
        if any(source.name == name for source in self.repo.data.get_sources()):
            raise Warning("fail: fonte com esse nome já existe.")

        repo = self.repo
        if remote_default is not None:
            print(Text.format("Adicionando fonte remota apontando para repositório git remoto {y}.", remote_default))
            url: str = ""
            settings = Settings()
            if not settings.has_alias_git(remote_default):
                raise Warning("fail: alias git remoto não encontrado.")
            url = settings.get_alias_git(remote_default)
            self.git_clone_repository(url)
            self.repo.data.set_source(RepSource(alias=name).set_git_source(target=url, branch=branch).set_filters(quest_filter, task_filter).set_writeable(writeable))
        elif remote_dir is not None:
            dir_path = Path(remote_dir)
            if not dir_path.exists() or not dir_path.is_dir():
                raise Warning("fail: diretório remoto não encontrado.")
            print(Text.format("Adicionando fonte remota apontando parao repositório no diretorio {y}.", dir_path))
            repo.data.set_source(RepSource(alias=name).set_local_source(target=dir_path).set_filters(quests=quest_filter, tasks=task_filter).set_writeable(writeable))
        elif remote_url is not None:
            print(Text.format("Adicionando fonte remota apontando para repositório git remoto {y}.", remote_url))
            self.git_clone_repository(remote_url)
            self.repo.data.set_source(RepSource(alias=name).set_git_source(target=remote_url, branch=branch).set_filters(quest_filter, task_filter).set_writeable(writeable))

        self.repo.save_config()
   

    def git_clone_repository(self, link: str) -> None:
        print(Text.format("Clonando repositório remoto {y}.", link))
        _ = self.repo.cache.get(link, force_update=True)
        print(Text.format("Repositório {y} clonado com sucesso.", link))
        


    def print_end_msg(self):
        print(Text.format("Voce pode acessar o repositório com o comando {g}", "tko open"))
        
