import type { GitHubQueryContext } from "@giselles-ai/giselle";
import { and, eq } from "drizzle-orm";
import { agents, db, githubRepositoryIndex, teams } from "@/db";
import {
	isOfficialGitHubRepositoryIndex,
	officialVectorStoreConfig,
} from "../../official-config";

/**
 * Resolves GitHub repository index from workspace context
 * Flow: workspace -> team -> repository index
 */
export async function resolveGitHubRepositoryIndex(
	context: GitHubQueryContext,
): Promise<number> {
	const { workspaceId, owner, repo } = context;

	// Input validation
	if (!workspaceId || workspaceId.trim().length === 0) {
		throw new Error("Workspace ID is required");
	}
	if (!owner || owner.trim().length === 0) {
		throw new Error("Repository owner is required");
	}
	if (!repo || repo.trim().length === 0) {
		throw new Error("Repository name is required");
	}

	// === Official Vector Store bypass ===
	// Check if there's an official repository index matching owner/repo
	if (officialVectorStoreConfig.teamDbId !== null) {
		const repositoryIndex = await db
			.select({
				dbId: githubRepositoryIndex.dbId,
				id: githubRepositoryIndex.id,
			})
			.from(githubRepositoryIndex)
			.where(
				and(
					eq(
						githubRepositoryIndex.teamDbId,
						officialVectorStoreConfig.teamDbId,
					),
					eq(githubRepositoryIndex.owner, owner),
					eq(githubRepositoryIndex.repo, repo),
				),
			)
			.limit(1);

		// Check if the found repository index is in the official list
		if (
			repositoryIndex.length > 0 &&
			isOfficialGitHubRepositoryIndex(repositoryIndex[0].id)
		) {
			return repositoryIndex[0].dbId;
		}
		// Fall through to normal flow if not found or not in official list
	}

	// Look up team from workspace
	const teamRecords = await db
		.select({ dbId: teams.dbId })
		.from(teams)
		.innerJoin(agents, eq(agents.teamDbId, teams.dbId))
		.where(eq(agents.workspaceId, workspaceId))
		.limit(1);

	if (teamRecords.length === 0) {
		throw new Error("Team not found");
	}
	const teamDbId = teamRecords[0].dbId;

	// Look up repository index
	const repositoryIndex = await db
		.select({ dbId: githubRepositoryIndex.dbId })
		.from(githubRepositoryIndex)
		.where(
			and(
				eq(githubRepositoryIndex.teamDbId, teamDbId),
				eq(githubRepositoryIndex.owner, owner),
				eq(githubRepositoryIndex.repo, repo),
			),
		)
		.limit(1);

	if (repositoryIndex.length === 0) {
		throw new Error("Repository index not found");
	}

	return repositoryIndex[0].dbId;
}
