import { getLogger } from "../../../logger.js";
import { getSubAgentFromProject } from "../utils/project.js";
import { createTaskHandler, createTaskHandlerConfig } from "../agents/generateTaskHandler.js";

//#region src/domains/run/data/agents.ts
const logger = getLogger("agents");
/**
* Create an AgentCard from database agent data
* Reusable function that standardizes agent card creation across the codebase
* Used for external discovery via /.well-known/agent.json endpoint
*/
function createAgentCard({ dbAgent, baseUrl }) {
	const description = dbAgent.description || "AI Agent";
	return {
		name: dbAgent.name,
		description,
		url: baseUrl ? `${baseUrl}/a2a` : "",
		version: "1.0.0",
		capabilities: {
			streaming: true,
			pushNotifications: false,
			stateTransitionHistory: false
		},
		defaultInputModes: ["text", "text/plain"],
		defaultOutputModes: ["text", "text/plain"],
		skills: [],
		...baseUrl && { provider: {
			organization: "Inkeep",
			url: baseUrl
		} }
	};
}
/**
* Generate an enhanced description that includes transfer and delegation information
* Used in generateTaskHandler to help agents understand what other agents can do
*
* @param baseDescription - The base description of the agent
* @param internalRelations - Pre-computed internal relations
* @param externalRelations - Pre-computed external relations
*/
function generateDescriptionWithRelationData(baseDescription, internalRelations, externalRelations, teamRelations) {
	const transfers = [...internalRelations.filter((rel) => rel.relationType === "transfer")];
	const delegates = [
		...internalRelations.filter((rel) => rel.relationType === "delegate"),
		...externalRelations.map((data) => data.externalAgent),
		...teamRelations.map((data) => data.targetAgent)
	];
	if (transfers.length === 0 && delegates.length === 0) return baseDescription;
	let enhancedDescription = baseDescription;
	if (transfers.length > 0) {
		const transferList = transfers.map((rel) => {
			return `- ${rel.externalAgent?.name || rel.name}: ${rel.externalAgent?.description || rel.description || ""}`;
		}).join("\n");
		enhancedDescription += `\n\nCan transfer to:\n${transferList}`;
	}
	if (delegates.length > 0) {
		const delegateList = delegates.map((rel) => {
			return `- ${rel.name}: ${rel.description || ""}`;
		}).join("\n");
		enhancedDescription += `\n\nCan delegate to:\n${delegateList}`;
	}
	return enhancedDescription;
}
/**
* Create a RegisteredAgent from database agent data
* Hydrates agent directly from database schema using types from schema.ts
*/
async function hydrateAgent({ dbAgent, executionContext, baseUrl, apiKey, credentialStoreRegistry, sandboxConfig }) {
	try {
		const taskHandlerConfig = await createTaskHandlerConfig({
			executionContext,
			subAgentId: dbAgent.id,
			baseUrl,
			apiKey,
			sandboxConfig
		});
		const { tenantId, projectId, agentId } = executionContext;
		const taskHandler = createTaskHandler(taskHandlerConfig, credentialStoreRegistry);
		const agentCard = createAgentCard({
			dbAgent: {
				...dbAgent,
				tenantId,
				projectId,
				agentId
			},
			baseUrl
		});
		return {
			subAgentId: dbAgent.id,
			tenantId,
			projectId,
			agentId,
			agentCard,
			taskHandler
		};
	} catch (error) {
		console.error(`❌ Failed to hydrate agent ${dbAgent.id}:`, error);
		throw error;
	}
}
async function getRegisteredAgent(params) {
	const { executionContext, credentialStoreRegistry, sandboxConfig } = params;
	const { agentId, subAgentId, baseUrl, apiKey, project } = executionContext;
	const dbAgent = getSubAgentFromProject({
		project,
		agentId,
		subAgentId
	});
	if (!dbAgent) {
		logger.warn({
			agentId,
			subAgentId
		}, "Could not find sub-agent in project");
		return null;
	}
	logger.info({
		agentId,
		subAgentId: dbAgent.id
	}, "Found sub-agent from project definition");
	return hydrateAgent({
		dbAgent,
		executionContext,
		baseUrl: `${baseUrl}/run/agents`,
		credentialStoreRegistry,
		apiKey,
		sandboxConfig
	});
}

//#endregion
export { createAgentCard, generateDescriptionWithRelationData, getRegisteredAgent };