from loguru import logger

from sweepai.config.client import (
    RESET_FILE,
    REVERT_CHANGED_FILES_TITLE,
    SWEEP_BAD_FEEDBACK,
    SWEEP_GOOD_FEEDBACK,
    SweepConfig,
    get_documentation_dict,
)
from sweepai.config.server import DISCORD_FEEDBACK_WEBHOOK_URL
from sweepai.core.context_pruning import get_relevant_context
from sweepai.core.entities import NoFilesException, SandboxResponse
from sweepai.core.sweep_bot import SweepBot, get_files_to_change, validate_file_change_requests

# from sandbox.sandbox_utils import Sandbox
from sweepai.handlers.create_pr import GITHUB_LABEL_NAME, create_pr_changes
from sweepai.utils.buttons import Button, ButtonList, create_action_buttons
from sweepai.utils.chat_logger import ChatLogger
from sweepai.utils.github_utils import ClonedRepo, get_github_client
from sweepai.utils.prompt_constructor import HumanMessagePrompt
from sweepai.utils.ticket_utils import prep_snippets


def make_pr(
    title,
    repo_description,
    summary,
    repo_full_name,
    installation_id,
    user_token,
    use_faster_model,
    username,
    chat_logger: ChatLogger,
    branch_name=None,
    rule=None,
):
    chat_logger.data["title"] = title
    _, repo_name = repo_full_name.split("/")
    # heavily copied code from on_ticket
    cloned_repo = ClonedRepo(
        repo_full_name,
        installation_id=installation_id,
        token=user_token,
        branch=branch_name,
    )
    logger.info("Fetching relevant files...")
    search_query = (title + summary).strip("\n")
    formatted_query = (f"{title.strip()}\n{summary.strip()}").strip("\n")
    repo_context_manager = prep_snippets(cloned_repo, search_query)
    repo_context_manager = get_relevant_context(
        formatted_query,
        repo_context_manager,
        chat_logger=chat_logger,
    )
    snippets = repo_context_manager.current_top_snippets
    tree = str(repo_context_manager.dir_obj)
    message_summary = summary
    # removed external search as it provides no real value and only adds noise
    # external_results = ExternalSearcher.extract_summaries(message_summary)
    # if external_results:
    #     message_summary += "\n\n" + external_results
    get_documentation_dict(cloned_repo.repo)
    human_message = HumanMessagePrompt(
        repo_name=repo_name,
        username=username,
        repo_description=repo_description.strip(),
        title=title,
        summary=message_summary,
        snippets=snippets,
        tree=tree,
    )

    _user_token, g = get_github_client(installation_id)
    repo = g.get_repo(repo_full_name)
    sweep_bot = SweepBot.from_system_message_content(
        human_message=human_message,
        repo=repo,
        is_reply=False,
        chat_logger=chat_logger,
        cloned_repo=cloned_repo,
    )
    file_change_requests, plan = get_files_to_change(
        relevant_snippets=repo_context_manager.current_top_snippets,
        read_only_snippets=repo_context_manager.read_only_snippets,
        problem_statement=formatted_query,
        repo_name=repo_name,
    )
    validate_file_change_requests(file_change_requests, repo_context_manager.cloned_repo)
    file_change_requests = sweep_bot.validate_file_change_requests(
        file_change_requests, branch_name
    )
    pull_request = sweep_bot.generate_pull_request()
    generator = create_pr_changes(
        file_change_requests,
        pull_request,
        sweep_bot,
        username,
        installation_id,
        chat_logger=chat_logger,
        base_branch=branch_name,
    )
    response = {"error": NoFilesException()}
    changed_files = []
    for item in generator:
        if isinstance(item, dict):
            response = item
            break
        (
            file_change_request,
            changed_file,
            sandbox_response,
            commit,
            file_change_requests,
        ) = item
        if changed_file:
            changed_files.append(file_change_request.filename)
        sandbox_response: SandboxResponse | None = sandbox_response
    pr_changes = response["pull_request"]
    pr_actions_message = (
        create_action_buttons(
            [
                SWEEP_GOOD_FEEDBACK,
                SWEEP_BAD_FEEDBACK,
            ],
            header="### PR Feedback (click)\n",
        )
        + "\n"
        if DISCORD_FEEDBACK_WEBHOOK_URL is not None
        else ""
    )
    rule_description = (
        f'### I created this PR to address this rule: \n"{rule}"\n'
        if rule
        else "I created this PR to fix the failing GitHub Actions."
    )
    pr = repo.create_pull(
        title=pr_changes.title,
        body=pr_actions_message + rule_description + pr_changes.body,
        head=pr_changes.pr_head,
        base=branch_name if branch_name else SweepConfig.get_branch(repo),
    )
    pr.add_to_assignees(username)
    buttons = []
    for changed_file in changed_files:
        buttons.append(Button(label=f"{RESET_FILE} {changed_file}"))
    revert_buttons_list = ButtonList(buttons=buttons, title=REVERT_CHANGED_FILES_TITLE)
    pr.create_issue_comment(revert_buttons_list.serialize())
    pr.add_to_labels(GITHUB_LABEL_NAME)

    return pr
