import type { PiTeamsConfig } from "../config/config.ts";
import type { TeamRunManifest } from "../state/types.ts";
import { appendTaskAttentionEvent } from "./attention-events.ts";
import type { CrewAgentRecord } from "./crew-agent-runtime.ts";
import { upsertCrewAgent } from "./crew-agent-records.ts";

export interface CrewControlConfig {
	enabled: boolean;
	needsAttentionAfterMs: number;
}

const DEFAULT_NEEDS_ATTENTION_MS = 60_000;

function positiveInt(value: unknown): number | undefined {
	return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : undefined;
}

export function resolveCrewControlConfig(config: PiTeamsConfig | undefined): CrewControlConfig {
	const raw = config as PiTeamsConfig & { control?: { enabled?: unknown; needsAttentionAfterMs?: unknown } } | undefined;
	return {
		enabled: raw?.control?.enabled === false ? false : true,
		needsAttentionAfterMs: positiveInt(raw?.control?.needsAttentionAfterMs) ?? DEFAULT_NEEDS_ATTENTION_MS,
	};
}

export function activityAgeMs(agent: CrewAgentRecord, now = Date.now()): number | undefined {
	const timestamp = agent.progress?.lastActivityAt ?? agent.startedAt;
	if (!timestamp) return undefined;
	const ms = now - new Date(timestamp).getTime();
	return Number.isFinite(ms) ? Math.max(0, ms) : undefined;
}

export function formatActivityAge(agent: CrewAgentRecord, now = Date.now()): string | undefined {
	const age = activityAgeMs(agent, now);
	if (age === undefined) return undefined;
	if (age < 1000) return "active now";
	const seconds = Math.floor(age / 1000);
	if (seconds < 60) return agent.progress?.activityState === "needs_attention" ? `no activity for ${seconds}s` : `active ${seconds}s ago`;
	const minutes = Math.floor(seconds / 60);
	return agent.progress?.activityState === "needs_attention" ? `no activity for ${minutes}m` : `active ${minutes}m ago`;
}

export function applyAttentionState(manifest: TeamRunManifest, agent: CrewAgentRecord, config: CrewControlConfig, now = Date.now()): CrewAgentRecord {
	if (!config.enabled || agent.status !== "running") return agent;
	const age = activityAgeMs(agent, now);
	if (age === undefined || age <= config.needsAttentionAfterMs) return agent;
	if (agent.progress?.activityState === "needs_attention") return agent;
	const updated: CrewAgentRecord = {
		...agent,
		progress: {
			...(agent.progress ?? { recentTools: [], recentOutput: [], toolCount: agent.toolUses ?? 0 }),
			activityState: "needs_attention",
		},
	};
	upsertCrewAgent(manifest, updated);
	appendTaskAttentionEvent({
		manifest,
		taskId: agent.taskId,
		message: `${agent.agent} needs attention (no observed activity for ${Math.floor(age / 1000)}s).`,
		data: { activityState: "needs_attention", reason: "idle", elapsedMs: age, taskId: agent.taskId, agentName: agent.agent, suggestedAction: "Check worker status, wait, steer, or cancel if needed." },
	});
	return updated;
}
