import { allAgents, discoverAgents } from "../agents/discover-agents.ts";
import { allTeams, discoverTeams } from "../teams/discover-teams.ts";
import { allWorkflows, discoverWorkflows } from "../workflows/discover-workflows.ts";
import { validateWorkflowForTeam } from "../workflows/validate-workflow.ts";

export interface ValidationIssue {
	level: "error" | "warning";
	resource: string;
	message: string;
}

export interface ValidationReport {
	issues: ValidationIssue[];
	agents: number;
	teams: number;
	workflows: number;
}

export function validateResources(cwd: string): ValidationReport {
	const agents = allAgents(discoverAgents(cwd));
	const teams = allTeams(discoverTeams(cwd));
	const workflows = allWorkflows(discoverWorkflows(cwd));
	const agentNames = new Set(agents.map((agent) => agent.name));
	const workflowNames = new Set(workflows.map((workflow) => workflow.name));
	const issues: ValidationIssue[] = [];

	for (const agent of agents) {
		const modelValues = [agent.model, ...(agent.fallbackModels ?? [])].filter((value): value is string => typeof value === "string" && value.length > 0);
		for (const model of modelValues) {
			if (/\s/.test(model)) {
				issues.push({ level: "warning", resource: `agent:${agent.name}`, message: `Model reference '${model}' contains whitespace.` });
			}
			if (model.includes("/") && model.split("/").some((part) => part.trim() === "")) {
				issues.push({ level: "warning", resource: `agent:${agent.name}`, message: `Model reference '${model}' has an empty provider/model segment.` });
			}
		}
	}

	for (const team of teams) {
		for (const role of team.roles) {
			if (!agentNames.has(role.agent)) {
				issues.push({ level: "error", resource: `team:${team.name}`, message: `Role '${role.name}' references unknown agent '${role.agent}'.` });
			}
		}
		if (team.defaultWorkflow && !workflowNames.has(team.defaultWorkflow)) {
			issues.push({ level: "error", resource: `team:${team.name}`, message: `defaultWorkflow references unknown workflow '${team.defaultWorkflow}'.` });
		}
		const workflow = workflows.find((candidate) => candidate.name === team.defaultWorkflow);
		if (workflow) {
			for (const error of validateWorkflowForTeam(workflow, team)) {
				issues.push({ level: "error", resource: `workflow:${workflow.name}`, message: `Team '${team.name}': ${error}` });
			}
		}
	}

	for (const workflow of workflows) {
		if (workflow.steps.length === 0) {
			issues.push({ level: "warning", resource: `workflow:${workflow.name}`, message: "Workflow has no steps." });
		}
	}

	return { issues, agents: agents.length, teams: teams.length, workflows: workflows.length };
}

export function formatValidationReport(report: ValidationReport): string {
	const lines = [
		"pi-crew resource validation:",
		`Agents: ${report.agents}`,
		`Teams: ${report.teams}`,
		`Workflows: ${report.workflows}`,
		`Issues: ${report.issues.length}`,
	];
	if (report.issues.length > 0) {
		lines.push("", ...report.issues.map((issue) => `- ${issue.level.toUpperCase()} ${issue.resource}: ${issue.message}`));
	}
	return lines.join("\n");
}
