import {
  createAppInstallation,
  createRepositoryMember,
  getAppInstallationByInstalltionId,
  prisma,
  upsertRepository,
} from "@codeflash-ai/common"
import { getUserRole } from "../../github/github-utils.js"
import { logger } from "../../utils/logger.js"

// Helper function to get installation ID using Octokit
export async function getInstallationId(
  installationOctokit: any,
  owner: string,
  repo: string,
): Promise<number> {
  const installation = await installationOctokit.rest.apps.getRepoInstallation({
    owner,
    repo,
  })
  return installation.data.id
}

//TODO:Remove Org creation after create script
export async function registerRepositoryAndMember(
  owner: string,
  repo: string,
  nickname: string,
  userId: string,
  installationOctokit: any,
): Promise<number> {
  const fullName = `${owner}/${repo}`
  const existingRepo = await prisma.repositories.findUnique({
    where: { full_name: fullName },
  })
  let validInstallationId = 0

  if (!existingRepo) {
    const installation = await installationOctokit.rest.apps.getRepoInstallation({
      owner,
      repo,
    })

    validInstallationId = installation.data.id
    // Check if installation exists in DB
    const installationExists = await getAppInstallationByInstalltionId(validInstallationId)
    if (!installationExists) {
      await createAppInstallation({
        installation_id: validInstallationId,
        account_id: installation.data.account.id,
        account_login: installation.data.account.login,
        account_type: installation.data.account.type,
      })
      logger.info("Upserting repository information", {
        endpoint: "/cfapi/github-repo-setup",
        operation: "upsert_repository",
        owner,
        repo,
      })
    } else {
      logger.info("Upserting repository information", {
        endpoint: "/cfapi/github-repo-setup",
        operation: "upsert_repository",
        owner,
        repo,
      })
    }

    const githubRepoResponse = await installationOctokit.rest.repos.get({
      owner,
      repo,
    })
    const { data: githubRepo } = githubRepoResponse

    const accountType = githubRepo.owner.type
    const isOrg = accountType === "Organization"

    const repository = await upsertRepository({
      github_repo_id: String(githubRepo.id),
      installation_id: validInstallationId,
      name: githubRepo.name,
      full_name: githubRepo.full_name,
      is_private: githubRepo.private,
    })

    const userRole = await getUserRole({
      octokit: installationOctokit,
      owner: githubRepo.owner.login,
      repo: githubRepo.name,
      username: nickname,
      isOrg,
    })
    logger.info("User role fetched", {
      endpoint: "/cfapi/github-repo-setup",
      operation: "get_user_role",
      owner,
      repo,
      userId,
    })

    await createRepositoryMember({
      repository_id: repository.id,
      user_id: userId,
      role: userRole,
    })
    logger.info("Repository member created", {
      endpoint: "/cfapi/github-repo-setup",
      operation: "create_repository_member",
      owner,
      repo,
      userId,
    })
  } else {
    // If repo exists, still fetch installation ID to return
    const installation = await installationOctokit.rest.apps.getRepoInstallation({
      owner,
      repo,
    })
    validInstallationId = installation.data.id
  }
  return validInstallationId
}
