import { getInstallationOctokitByOwner } from "../github/github-utils"
import { githubApp } from "../github/github-app"

function updateOptimizationsDict(
  dict: { [key: string]: [string] },
  path: string,
  funcName: string,
) {
  if (path in dict) {
    dict[path].push(funcName)
  } else {
    dict[path] = [funcName]
  }
}

export async function verifyExistingOptimizations(req, res) {
  const { repo_owner, repo_name, pr_number } = req.body

  const octokit = await getInstallationOctokitByOwner(githubApp, repo_owner, repo_name)
  if (octokit instanceof Error) {
    return res.status(500).send({ error: octokit.message })
  }
  console.log(`Got installation Octokit for ${repo_owner}/${repo_name}`)

  let pr
  try {
    pr = await octokit.rest.pulls.get({
      owner: repo_owner,
      repo: repo_name,
      pull_number: pr_number,
    })
  } catch (error: any) {
    if (error.status === 404) {
      return res.status(404).send(`PR ${pr_number} not found for ${repo_owner}/${repo_name}`)
    }
    console.error("Error getting PR:", error)
    return res
      .status(404)
      .send({ message: `Error getting PR ${pr_number} for ${repo_owner}/${repo_name}` })
  }

  const optimizations_dict: { [key: string]: Set<string> } = {}

  if (pr.data.body.includes("This pull request contains optimizations for PR")) {
    const pr_body = pr.data.body.split("\n")
    for (const line of pr_body) {
      if (line.includes("📄")) {
        const split = line.split(" ")
        const function_name: string = split[2].replace(/`/g, "").trim()
        const file_path: string = split[4].replace(/`/g, "").trim()
        if (!optimizations_dict[file_path]) {
          optimizations_dict[file_path] = new Set()
        }
        optimizations_dict[file_path].add(function_name)
      }
    }
  }

  let pr_messages
  try {
    pr_messages = await octokit.rest.issues.listComments({
      owner: repo_owner,
      repo: repo_name,
      issue_number: pr_number,
    })
  } catch (error: any) {
    console.error("Error getting PR messages:", error)
    return res
      .status(404)
      .send({ error: `Error getting PR messages for ${repo_owner}/${repo_name}` })
  }

  for (const message of pr_messages.data) {
    if (message.body.includes("Codeflash found optimizations for this PR")) {
      const pr_body = message.body.split("\n")
      for (const line of pr_body) {
        if (line.includes("📄")) {
          const split = line.split(" ")
          const function_name: string = split[2].replace(/`/g, "").trim()
          const file_path: string = split[4].replace(/`/g, "").trim()
          if (!optimizations_dict[file_path]) {
            optimizations_dict[file_path] = new Set()
          }
          optimizations_dict[file_path].add(function_name)
        }
      }
    }
  }

  if (Object.keys(optimizations_dict).length === 0) {
    return res.status(404).send({ message: "No optimizations found for this PR" })
  }

  const response_dict: { [key: string]: string[] } = {}
  for (const key in optimizations_dict) {
    response_dict[key] = Array.from(optimizations_dict[key])
  }

  return res.status(200).send(response_dict)
}
