import { normalizePluginClientId } from "@/lib/plugin-catalog"

export type PluginSpaceInfo = {
	pluginId: "claude-code" | "openclaw" | "opencode" | "codex" | "amp" | "hermes"
	label: string
	iconSrc: string | null
	projectId?: string
}

type PluginDef = {
	id: PluginSpaceInfo["pluginId"]
	label: string
	iconSrc: string | null
	prefixes: string[]
}

const PLUGINS: PluginDef[] = [
	{
		id: "claude-code",
		label: "Claude Code",
		iconSrc: "/images/plugins/claude-code.svg",
		prefixes: ["claudecode"],
	},
	{
		id: "openclaw",
		label: "OpenClaw",
		iconSrc: "/images/plugins/openclaw.svg",
		prefixes: ["openclaw"],
	},
	{
		id: "opencode",
		label: "OpenCode",
		iconSrc: "/images/plugins/opencode.svg",
		prefixes: ["opencode"],
	},
	{
		id: "codex",
		label: "Codex",
		iconSrc: "/images/plugins/codex.png",
		prefixes: ["codex"],
	},
	{
		id: "amp",
		label: "Amp",
		iconSrc: null,
		prefixes: ["amp"],
	},
	{
		id: "hermes",
		label: "Hermes",
		iconSrc: "/images/plugins/hermes.svg",
		prefixes: ["hermes"],
	},
]

function parsePluginRest(rest: string): { projectId?: string } {
	if (!rest || rest === "default" || rest === "global") {
		return { projectId: "Global" }
	}
	const userMatch = rest.match(/^user[_-]([0-9a-f]{6,64})$/i)
	if (userMatch?.[1]) return { projectId: `User · ${userMatch[1].slice(0, 6)}` }
	const projectMatch = rest.match(/^project[_-]([0-9a-f]{6,64})$/i)
	if (projectMatch?.[1]) return { projectId: projectMatch[1].slice(0, 6) }
	const hexOnly = rest.match(/^([0-9a-f]{6,64})$/i)
	if (hexOnly?.[1]) return { projectId: hexOnly[1].slice(0, 6) }
	return { projectId: rest.slice(0, 24) }
}

const PLUGIN_ICON_BY_LABEL: Record<string, string> = {
	"Claude Code": "/images/plugins/claude-code.svg",
	OpenClaw: "/images/plugins/openclaw.svg",
	OpenCode: "/images/plugins/opencode.svg",
	Codex: "/images/plugins/codex.png",
	Hermes: "/images/plugins/hermes.svg",
}

export function pluginIconByLabel(
	label: string | null | undefined,
): string | null {
	if (!label) return null
	return PLUGIN_ICON_BY_LABEL[label] ?? null
}

export function pluginInitial(label: string | null | undefined): string {
	if (!label) return "?"
	return label.trim().charAt(0).toUpperCase() || "?"
}

export type PluginDocSource = {
	pluginId: "claude-code"
	label: string
	iconSrc: string
	projectName?: string
	formatLabel: string
	type: "session_turn" | "project-knowledge" | "manual" | "unknown"
}

function formatLabelForType(t: string | undefined): {
	formatLabel: string
	type: PluginDocSource["type"]
} {
	switch (t) {
		case "session_turn":
			return { formatLabel: "Session", type: "session_turn" }
		case "project-knowledge":
			return { formatLabel: "Project knowledge", type: "project-knowledge" }
		case "manual":
			return { formatLabel: "Note", type: "manual" }
		default:
			return { formatLabel: "Note", type: "unknown" }
	}
}

export function detectPluginSource(
	metadata: Record<string, unknown> | null | undefined,
	documentSource?: string | null,
): PluginDocSource | null {
	const sourceFromMeta =
		metadata && typeof metadata.sm_source === "string"
			? metadata.sm_source
			: null
	const source = (documentSource ?? sourceFromMeta)?.trim().toLowerCase()
	if (source !== "claude-code-plugin" && source !== "claude-code") return null

	const md = metadata ?? {}
	const project =
		typeof md.project === "string" && md.project.trim()
			? md.project.trim()
			: undefined
	const t = typeof md.type === "string" ? md.type : undefined
	const { formatLabel, type } = formatLabelForType(t)

	return {
		pluginId: "claude-code",
		label: "Claude Code",
		iconSrc: "/images/plugins/claude-code.svg",
		projectName: project,
		formatLabel,
		type,
	}
}

type DocumentSpaceCandidate = {
	containerTags?: string[]
	memoryEntries?: Array<{ spaceContainerTag?: string | null }> | null
}

function catalogIdForPluginSpace(
	pluginId: PluginSpaceInfo["pluginId"],
): string {
	return pluginId.replace(/-/g, "_")
}

/** Resolve the best container tag for a tool/plugin document. */
export function getToolDocumentSpace(
	document: DocumentSpaceCandidate,
	pluginClientId?: string | null,
): string | null {
	const containerTags = document.containerTags ?? []
	const memorySpaceTags = (document.memoryEntries ?? [])
		.map((entry) => entry.spaceContainerTag)
		.filter((tag): tag is string => !!tag)
	const allTags = [...containerTags, ...memorySpaceTags]

	if (pluginClientId) {
		const normalizedClient = normalizePluginClientId(pluginClientId)
		for (const tag of allTags) {
			const pluginSpace = detectPluginSpace(tag)
			if (
				pluginSpace &&
				catalogIdForPluginSpace(pluginSpace.pluginId) === normalizedClient
			) {
				return tag
			}
		}
	}

	for (const tag of allTags) {
		if (detectPluginSpace(tag)) return tag
	}

	return allTags[0] ?? null
}

export function detectPluginSpace(
	containerTag: string,
): PluginSpaceInfo | null {
	if (!containerTag) return null

	for (const plugin of PLUGINS) {
		for (const prefix of plugin.prefixes) {
			if (containerTag === prefix) {
				return {
					pluginId: plugin.id,
					label: plugin.label,
					iconSrc: plugin.iconSrc,
					projectId: "Global",
				}
			}
			const separator = containerTag[prefix.length]
			if (
				containerTag.startsWith(prefix) &&
				(separator === "_" || separator === "-")
			) {
				const rest = containerTag.slice(prefix.length + 1)
				const parsed = parsePluginRest(rest)
				return {
					pluginId: plugin.id,
					label: plugin.label,
					iconSrc: plugin.iconSrc,
					projectId: parsed.projectId,
				}
			}
		}
	}

	return null
}
