export type ZoneGazePluginId =
	| "zonegaze-flow"
	| "zonegaze-whispr"
	| "zonegaze-chat"
	| "zonegaze-joplin"
	| "zonegaze-code"
	| "zonegaze-git"
	| "open-design"
	| "exo"
	| "zonegaze-research"
	| "zonegaze-social-studio";

export type MatrixPluginCapability =
	| "dictation"
	| "project-context"
	| "chat"
	| "notes"
	| "file-workspace"
	| "git"
	| "design-artifact"
	| "local-model-runtime"
	| "deep-research"
	| "social-studio";

export type MatrixPluginPackageStatus = "ready" | "partial" | "blocked";
export type MatrixPluginHealth = "ready" | "starting" | "blocked" | "unavailable";

export interface MatrixPluginRuntimeManifest {
	pluginId: ZoneGazePluginId;
	packageStatus: MatrixPluginPackageStatus;
	sourcePath: string;
	capabilities: readonly MatrixPluginCapability[];
	settingsSections: readonly string[];
	blockedReason?: string;
}

export type MatrixPluginInstallReadiness =
	| {
			installable: true;
			status: "ready";
	  }
	| {
			installable: false;
			status: "blocked";
			reason: string;
	  }
	| {
			installable: false;
			status: "unknown";
			reason: string;
	  };

export interface MatrixCapabilityProviderState {
	pluginId: ZoneGazePluginId;
	installed: boolean;
	health: MatrixPluginHealth;
	capabilities: readonly MatrixPluginCapability[];
}

export interface MatrixCapabilityRegistry {
	getProvider(capability: MatrixPluginCapability): MatrixCapabilityProviderState | null;
	hasCapability(capability: MatrixPluginCapability): boolean;
}

const MATRIX_PLUGIN_RUNTIME_MANIFESTS: readonly MatrixPluginRuntimeManifest[] = [
	{
		pluginId: "zonegaze-flow",
		packageStatus: "ready",
		sourcePath: "flow/",
		capabilities: ["project-context"],
		settingsSections: ["Agents", "Git prompts", "Project context", "Appearance"],
	},
	{
		pluginId: "zonegaze-whispr",
		packageStatus: "ready",
		sourcePath: "plugins/whispr/",
		capabilities: ["dictation"],
		settingsSections: ["Dictation target", "Voice input", "History"],
	},
	{
		pluginId: "zonegaze-code",
		packageStatus: "partial",
		sourcePath: "plugins/code/",
		capabilities: ["file-workspace"],
		settingsSections: ["Workspace launch", "IDE runtime", "Branding"],
	},
	{
		pluginId: "zonegaze-git",
		packageStatus: "ready",
		sourcePath: "plugins/git/",
		capabilities: ["git"],
		settingsSections: ["Device setup", "Repository defaults", "Advanced Git UI"],
	},
	{
		pluginId: "open-design",
		packageStatus: "ready",
		sourcePath: "plugins/open-design/",
		capabilities: ["design-artifact"],
		settingsSections: ["Design workspace", "Automations", "Integrations"],
	},
	{
		pluginId: "zonegaze-chat",
		packageStatus: "ready",
		sourcePath: "plugins/chat/",
		capabilities: ["chat"],
		settingsSections: ["Conversation memory", "Project context"],
	},
	{
		pluginId: "zonegaze-joplin",
		packageStatus: "ready",
		sourcePath: "plugins/joplin/",
		capabilities: ["notes"],
		settingsSections: ["Notes workspace", "Knowledge sync", "Project context"],
	},
	{
		pluginId: "exo",
		packageStatus: "ready",
		sourcePath: "plugins/exo/",
		capabilities: ["local-model-runtime"],
		settingsSections: ["Cluster runtime", "Local model APIs"],
	},
	{
		pluginId: "zonegaze-research",
		packageStatus: "ready",
		sourcePath: "plugins/research/",
		capabilities: ["deep-research"],
		settingsSections: ["Research services", "Model providers", "Artifact library"],
	},
	{
		pluginId: "zonegaze-social-studio",
		packageStatus: "ready",
		sourcePath: "plugins/social-studio/",
		capabilities: ["social-studio"],
		settingsSections: ["Workspace", "Connectors", "Publishing adapters", "Analytics adapters", "Automation"],
	},
];

export function getMatrixPluginRuntimeManifest(pluginId: string): MatrixPluginRuntimeManifest | null {
	return MATRIX_PLUGIN_RUNTIME_MANIFESTS.find((manifest) => manifest.pluginId === pluginId) ?? null;
}

export function getMatrixPluginRuntimeManifests(): readonly MatrixPluginRuntimeManifest[] {
	return MATRIX_PLUGIN_RUNTIME_MANIFESTS;
}

export function getPluginInstallReadiness(pluginId: string): MatrixPluginInstallReadiness {
	const manifest = getMatrixPluginRuntimeManifest(pluginId);
	if (!manifest) {
		return {
			installable: false,
			reason: `Unknown Matrix plugin: ${pluginId}`,
			status: "unknown",
		};
	}
	if (manifest.packageStatus === "blocked") {
		return {
			installable: false,
			reason: manifest.blockedReason ?? `${manifest.pluginId} is not ready to install.`,
			status: "blocked",
		};
	}
	return {
		installable: true,
		status: "ready",
	};
}

export function createMatrixCapabilityProviderStates(
	installedPluginIds: readonly string[],
): MatrixCapabilityProviderState[] {
	const providers: MatrixCapabilityProviderState[] = [];
	const seenPluginIds = new Set<ZoneGazePluginId>();
	for (const pluginId of installedPluginIds) {
		const manifest = getMatrixPluginRuntimeManifest(pluginId);
		if (!manifest || seenPluginIds.has(manifest.pluginId) || !getPluginInstallReadiness(pluginId).installable) {
			continue;
		}
		seenPluginIds.add(manifest.pluginId);
		providers.push({
			pluginId: manifest.pluginId,
			installed: true,
			health: "ready",
			capabilities: manifest.capabilities,
		});
	}
	return providers;
}

export function createMatrixCapabilityRegistry(
	providers: readonly MatrixCapabilityProviderState[],
): MatrixCapabilityRegistry {
	const readyProviders = providers.filter((provider) => provider.installed && provider.health === "ready");
	return {
		getProvider(capability) {
			return readyProviders.find((provider) => provider.capabilities.includes(capability)) ?? null;
		},
		hasCapability(capability) {
			return readyProviders.some((provider) => provider.capabilities.includes(capability));
		},
	};
}
