import { rpcCall } from "./rpc";

export type AgentStatusValue = "pending" | "running" | "completed" | "failed";

export interface AgentInfo {
	story_id: string;
	agent_name: string;
	status: AgentStatusValue;
	session_id: string | null;
	worktree_path: string | null;
	base_branch: string | null;
	log_session_id: string | null;
}

export interface AgentEvent {
	type:
		| "status"
		| "output"
		| "thinking"
		| "agent_json"
		| "done"
		| "error"
		| "warning";
	story_id?: string;
	agent_name?: string;
	status?: string;
	text?: string;
	data?: unknown;
	session_id?: string | null;
	message?: string;
}

export interface AgentConfigInfo {
	name: string;
	role: string;
	stage: string | null;
	model: string | null;
	allowed_tools: string[] | null;
	max_turns: number | null;
	max_budget_usd: number | null;
}

export const agentsApi = {
	startAgent(storyId: string, agentName?: string) {
		return rpcCall<AgentInfo>("agents.start", {
			story_id: storyId,
			agent_name: agentName,
		});
	},

	stopAgent(storyId: string, agentName: string) {
		return rpcCall<boolean>("agents.stop", {
			story_id: storyId,
			agent_name: agentName,
		});
	},

	listAgents(_baseUrl?: string) {
		return rpcCall<AgentInfo[]>("active_agents.list");
	},

	getAgentConfig(_baseUrl?: string) {
		return rpcCall<AgentConfigInfo[]>("agent_config.list");
	},

	reloadConfig() {
		return rpcCall<AgentConfigInfo[]>("agent_config.list");
	},

	getAgentOutput(storyId: string, agentName: string, _baseUrl?: string) {
		return rpcCall<{ output: string }>("agents.get_output", {
			story_id: storyId,
			agent_name: agentName,
		});
	},
};

/**
 * Subscribe to SSE events for a running agent.
 * Returns a cleanup function to close the connection.
 */
export function subscribeAgentStream(
	storyId: string,
	agentName: string,
	onEvent: (event: AgentEvent) => void,
	onError?: (error: Event) => void,
): () => void {
	const url = `/agents/${encodeURIComponent(storyId)}/${encodeURIComponent(agentName)}/stream`;

	const eventSource = new EventSource(url);

	eventSource.onmessage = (e) => {
		try {
			const data = JSON.parse(e.data) as AgentEvent;
			onEvent(data);

			// Close on terminal events
			if (
				data.type === "done" ||
				data.type === "error" ||
				(data.type === "status" && data.status === "stopped")
			) {
				eventSource.close();
			}
		} catch (err) {
			console.error("Failed to parse agent event:", err);
		}
	};

	eventSource.onerror = (e) => {
		onError?.(e);
		eventSource.close();
	};

	return () => {
		eventSource.close();
	};
}
