import logging
from typing import List, Any, Dict, Optional

from langchain_core.tools import BaseTool
from langchain_core.language_models import BaseChatModel

from codemie_tools.base.base_toolkit import BaseToolkit
from codemie_tools.base.models import ToolKit, Tool, ToolSet
from codemie_tools.git.bitbucket.bitbucket_toolkit import CustomBitbucketToolkit
from codemie_tools.git.github.github_toolkit import CustomGitHubToolkit
from codemie_tools.git.github.tools_vars import (
    SET_ACTIVE_BRANCH_TOOL, UPDATE_FILE_TOOL, LIST_BRANCHES_TOOL,
    DELETE_FILE_TOOL, CREATE_FILE_TOOL, CREATE_PULL_REQUEST_TOOL, CREATE_GIT_BRANCH_TOOL, GET_PR_CHANGES,
    CREATE_PR_CHANGE_COMMENT, UPDATE_FILE_DIFF_TOOL
)
from codemie_tools.git.gitlab.gitlab_toolkit import CustomGitLabToolkit

logger = logging.getLogger(__name__)

TYPE_GITHUB: str = "github"
TYPE_GITLAB: str = "gitlab"
TYPE_BITBUCKET: str = "bitbucket"
TYPE_UNKNOWN: str = "unknown"


class GitToolkitUI(ToolKit):
    toolkit: ToolSet = ToolSet.GIT
    settings_config: bool = True
    tools: List[Tool] = [
        Tool.from_metadata(CREATE_GIT_BRANCH_TOOL),
        Tool.from_metadata(SET_ACTIVE_BRANCH_TOOL),
        Tool.from_metadata(LIST_BRANCHES_TOOL),
        Tool.from_metadata(CREATE_FILE_TOOL),
        Tool.from_metadata(UPDATE_FILE_TOOL),
        Tool.from_metadata(UPDATE_FILE_DIFF_TOOL),
        Tool.from_metadata(DELETE_FILE_TOOL),
        Tool.from_metadata(CREATE_PULL_REQUEST_TOOL),
        Tool.from_metadata(GET_PR_CHANGES),
        Tool.from_metadata(CREATE_PR_CHANGE_COMMENT),
    ]


class GitToolkit(BaseToolkit):
    git_toolkit: Any = None

    @classmethod
    def get_tools_ui_info(cls, *args, **kwargs):
        return GitToolkitUI().model_dump()

    def get_tools(self) -> List[BaseTool]:
        tools = []
        for tool in self.git_toolkit.get_tools():
            tool.name = tool.name.replace(" ", "_")
            tools.append(tool)
        return tools

    @classmethod
    def get_toolkit(cls, configs: Dict[str, Any], llm_model: Optional[BaseChatModel] = None):
        repo_type = configs.get("repo_type", TYPE_UNKNOWN)
        if repo_type == TYPE_GITLAB:
            toolkit = CustomGitLabToolkit.get_toolkit(configs=configs, llm_model=llm_model)
        elif repo_type == TYPE_GITHUB:
            toolkit = CustomGitHubToolkit.get_toolkit(configs=configs, llm_model=llm_model)
        elif repo_type == TYPE_BITBUCKET:
            toolkit = CustomBitbucketToolkit.get_toolkit(configs, llm_model)
        else:
            logger.error(f"Unknown repository type: {repo_type}")
            raise ValueError("Unknown repository type")
        return GitToolkit(git_toolkit=toolkit)
