import type {
	BulkResult,
	CursorPaginatedResult,
	Key,
	KeyDeleted,
	KeysBulkDeleted,
} from "@lokalise/node-api";
import {
	formatBulletList,
	formatEmptyState,
	formatErrorList,
	formatFooter,
	formatHeading,
	formatPaginationInfo,
	formatPercentage,
	formatSafeArray,
	formatTable,
	formatTruncated,
} from "../../shared/utils/formatter.util.js";

/**
 * @namespace KeysFormatter
 * @description Utility functions for formatting Lokalise Keys API responses into readable formats.
 *              Provides consistent Markdown formatting for various key operations.
 */

/**
 * @function formatKeysList
 * @description Formats a list of keys into a comprehensive, LLM-friendly Markdown report
 * @memberof KeysFormatter
 * @param {any} response - The raw response from the Lokalise Keys API list operation
 * @param {string} projectId - The project ID for context
 * @returns {string} Formatted Markdown string containing the keys list
 */
export function formatKeysList(
	response: CursorPaginatedResult<Key>,
	projectId: string,
): string {
	const keys = response.items || [];
	const hasNextCursor = response.hasNextCursor();

	if (keys.length === 0) {
		const suggestions = [
			"The project is newly created",
			"All keys have been deleted",
			"Filter criteria excluded all keys",
			"You may not have permission to view keys",
		];
		return [
			formatHeading("Translation Keys Analysis", 1),
			"",
			formatHeading(`Project: ${projectId}`, 2),
			"",
			formatEmptyState("keys", "this project", suggestions),
			formatFooter("Analysis completed"),
		].join("\n");
	}

	const lines: string[] = [];
	lines.push(formatHeading("Translation Keys Analysis", 1));
	lines.push("");
	lines.push(formatHeading(`Project: ${projectId}`, 2));
	lines.push("");

	// Helper function to get primary key name
	const getPrimaryKeyName = (keyName: unknown): string => {
		if (!keyName || typeof keyName !== "object") return "Unnamed";
		const names = keyName as Record<string, string>;
		return names.web || names.ios || names.android || names.other || "Unnamed";
	};

	// Calculate comprehensive statistics
	const stats = {
		totalKeys: keys.length,
		platformCounts: {
			ios: keys.filter((k) => k.platforms?.includes("ios")).length,
			android: keys.filter((k) => k.platforms?.includes("android")).length,
			web: keys.filter((k) => k.platforms?.includes("web")).length,
			other: keys.filter((k) => k.platforms?.includes("other")).length,
		},
		statusCounts: {
			hidden: keys.filter((k) => k.is_hidden).length,
			archived: keys.filter((k) => k.is_archived).length,
			plural: keys.filter((k) => k.is_plural).length,
			withDescription: keys.filter(
				(k) => k.description && k.description.trim() !== "",
			).length,
			withTags: keys.filter((k) => k.tags && k.tags.length > 0).length,
			withComments: keys.filter((k) => k.comments && k.comments.length > 0)
				.length,
			withScreenshots: keys.filter(
				(k) => k.screenshots && k.screenshots.length > 0,
			).length,
		},
		translationCounts: {
			total: keys.reduce((sum, k) => sum + (k.translations?.length || 0), 0),
			withTranslations: keys.filter(
				(k) => k.translations && k.translations.length > 0,
			).length,
		},
	};

	// Executive summary
	lines.push(formatHeading("Executive Summary", 2));
	lines.push("");
	lines.push(`**${stats.totalKeys} translation keys** found in this project.`);
	lines.push("");

	// Key Distribution
	lines.push(formatHeading("Key Distribution", 3));
	lines.push("");
	for (const [platform, count] of Object.entries(stats.platformCounts)) {
		const percentage = formatPercentage(count, stats.totalKeys);
		lines.push(
			`- **${platform.toUpperCase()} Platform:** ${count} keys (${percentage})`,
		);
	}
	lines.push("");

	// Content Quality Indicators
	lines.push(formatHeading("Content Quality Indicators", 3));
	lines.push("");
	const qualityStats = [
		{
			label: "Keys with Descriptions",
			value: stats.statusCounts.withDescription,
		},
		{ label: "Keys with Tags", value: stats.statusCounts.withTags },
		{ label: "Keys with Comments", value: stats.statusCounts.withComments },
		{
			label: "Keys with Screenshots",
			value: stats.statusCounts.withScreenshots,
		},
	];

	for (const stat of qualityStats) {
		const percentage = formatPercentage(stat.value, stats.totalKeys);
		lines.push(
			`- **${stat.label}:** ${stat.value}/${stats.totalKeys} (${percentage})`,
		);
	}
	lines.push("");

	// Status Overview
	lines.push(formatHeading("Status Overview", 3));
	lines.push("");
	const statusStats = [
		{ label: "Hidden Keys", value: stats.statusCounts.hidden },
		{ label: "Archived Keys", value: stats.statusCounts.archived },
		{ label: "Plural Keys", value: stats.statusCounts.plural },
	];

	for (const stat of statusStats) {
		const percentage = formatPercentage(stat.value, stats.totalKeys);
		lines.push(`- **${stat.label}:** ${stat.value} (${percentage})`);
	}
	lines.push("");

	if (stats.translationCounts.withTranslations > 0) {
		// Translation insights
		lines.push(formatHeading("Translation Status", 3));
		lines.push("");
		lines.push(
			`- **Keys with Translation Data:** ${stats.translationCounts.withTranslations}/${stats.totalKeys}`,
		);
		lines.push(`- **Total Translations:** ${stats.translationCounts.total}`);
		const avgTranslations =
			Math.round(
				(stats.translationCounts.total /
					stats.translationCounts.withTranslations) *
					100,
			) / 100;
		lines.push(`- **Average Translations per Key:** ${avgTranslations}`);
		lines.push("");
	}

	// Pagination information
	lines.push(
		formatPaginationInfo(hasNextCursor, response.nextCursor, keys.length),
	);

	// Detailed keys table with enhanced information
	lines.push(formatHeading("Detailed Keys Inventory", 2));
	lines.push("");

	const tableData = keys.map((key) => ({
		id: key.key_id || "N/A",
		keyName: getPrimaryKeyName(key.key_name),
		description: key.description || "*No description*",
		platforms: formatSafeArray(key.platforms),
		tags:
			key.tags && key.tags.length > 0
				? key.tags.length > 2
					? `${key.tags.slice(0, 2).join(", ")}+${key.tags.length - 2}`
					: key.tags.join(", ")
				: "None",
		status: getKeyStatus(key),
		context: key.context || "None",
	}));

	const table = formatTable(tableData, [
		{ key: "id", header: "ID" },
		{ key: "keyName", header: "Key Name", formatter: (v) => `\`${v}\`` },
		{ key: "description", header: "Description", maxWidth: 40 },
		{ key: "platforms", header: "Platforms" },
		{ key: "tags", header: "Tags" },
		{ key: "status", header: "Status" },
		{ key: "context", header: "Context", maxWidth: 30 },
	]);

	lines.push(table);
	lines.push("");

	// Advanced insights section
	lines.push(formatHeading("Advanced Insights", 2));
	lines.push("");

	// Find keys that might need attention
	const recommendations: string[] = [];
	const missingDescription = keys.filter(
		(k) => !k.description || k.description.trim() === "",
	);
	const noTags = keys.filter((k) => !k.tags || k.tags.length === 0);
	const noPlatforms = keys.filter(
		(k) => !k.platforms || k.platforms.length === 0,
	);
	const hiddenKeys = keys.filter((k) => k.is_hidden);
	const archivedKeys = keys.filter((k) => k.is_archived);

	if (missingDescription.length > 0) {
		recommendations.push(
			`**${missingDescription.length} keys without descriptions** - consider adding descriptions for better translator context`,
		);
	}
	if (noTags.length > 0) {
		recommendations.push(
			`**${noTags.length} keys without tags** - tags help with organization and filtering`,
		);
	}
	if (noPlatforms.length > 0) {
		recommendations.push(
			`**${noPlatforms.length} keys without platform assignments** - may indicate configuration issues`,
		);
	}
	if (hiddenKeys.length > 0) {
		recommendations.push(
			`**${hiddenKeys.length} hidden keys** - verify these should remain hidden from translators`,
		);
	}
	if (archivedKeys.length > 0) {
		recommendations.push(
			`**${archivedKeys.length} archived keys** - these are inactive and may need cleanup`,
		);
	}

	if (recommendations.length > 0) {
		lines.push(formatHeading("Recommendations for Improvement", 3));
		lines.push("");
		for (const recommendation of recommendations) {
			lines.push(`- ${recommendation}`);
		}
		lines.push("");
	}

	// Platform-specific insights
	lines.push(formatHeading("Platform-Specific Analysis", 3));
	lines.push("");
	const platformData = [
		{ name: "iOS", count: stats.platformCounts.ios },
		{ name: "Android", count: stats.platformCounts.android },
		{ name: "Web", count: stats.platformCounts.web },
		{ name: "Other", count: stats.platformCounts.other },
	];

	for (const platform of platformData) {
		const percentage = Math.round((platform.count / stats.totalKeys) * 100);
		let coverage: string;
		if (percentage === 100) {
			coverage = "- Universal coverage ✅";
		} else if (percentage > 75) {
			coverage = "- High coverage";
		} else if (percentage > 50) {
			coverage = "- Moderate coverage";
		} else if (percentage > 0) {
			coverage = "- Limited coverage ⚠️";
		} else {
			coverage = "- No keys assigned ❌";
		}
		lines.push(
			`- **${platform.name}:** ${platform.count} keys (${percentage}%) ${coverage}`,
		);
	}
	lines.push("");

	// Summary section for LLM reasoning
	lines.push(formatHeading("Summary for Analysis", 2));
	lines.push("");
	lines.push(
		`**Project ${projectId} contains ${stats.totalKeys} translation keys** with the following characteristics:`,
	);
	lines.push("");

	const mostUsedPlatform = Object.entries(stats.platformCounts).reduce(
		(a, b) => (a[1] > b[1] ? a : b),
	)[0];
	const summaryStats = [
		`Most used platform: ${mostUsedPlatform}`,
		`Content maturity: ${formatPercentage(stats.statusCounts.withDescription, stats.totalKeys)} of keys have descriptions`,
		`Organization level: ${formatPercentage(stats.statusCounts.withTags, stats.totalKeys)} of keys are tagged`,
		`Collaboration activity: ${stats.statusCounts.withComments} keys have comments`,
		`Visual context: ${stats.statusCounts.withScreenshots} keys have screenshots`,
	];

	for (const stat of summaryStats) {
		lines.push(`- **${stat}**`);
	}

	if (stats.statusCounts.archived > 0 || stats.statusCounts.hidden > 0) {
		lines.push(
			`- **Maintenance needed:** ${stats.statusCounts.archived + stats.statusCounts.hidden} keys are archived or hidden`,
		);
	}
	lines.push("");

	// Final metadata
	const contextMessage = hasNextCursor
		? "Additional keys available - use cursor pagination to fetch more"
		: `Showing ${keys.length} keys from project \`${projectId}\``;
	lines.push(formatFooter("Analysis completed", contextMessage));

	return lines.join("\n");
}

/**
 * @function formatKeyDetails
 * @description Formats detailed information about a single key with comprehensive LLM-friendly output
 * @memberof KeysFormatter
 * @param {Key} key - The key object from Lokalise API
 * @param {string} projectId - The project ID for context
 * @returns {string} Formatted Markdown string containing the key details
 */
export function formatKeyDetails(key: Key, projectId: string): string {
	const lines: string[] = [];
	lines.push(formatHeading("Translation Key Details", 1));
	lines.push("");

	// Helper function to safely format objects
	const safeStringify = (obj: unknown): string => {
		if (obj === null || obj === undefined) return "Not set";
		if (typeof obj === "string") return obj;
		if (typeof obj === "number" || typeof obj === "boolean") return String(obj);
		try {
			return JSON.stringify(obj, null, 2);
		} catch {
			return String(obj);
		}
	};

	// Helper function to format platform-specific names/filenames
	const formatPlatformObject = (obj: unknown): string => {
		if (!obj || typeof obj !== "object") return "Not configured";

		const platforms = ["ios", "android", "web", "other"] as const;
		const items: string[] = [];

		for (const platform of platforms) {
			const value = (obj as Record<string, string>)[platform];
			if (value) {
				items.push(`- **${platform.toUpperCase()}:** \`${value}\``);
			}
		}

		return items.length > 0
			? items.join("\n")
			: "No platform-specific values set";
	};

	// Core identification
	const coreInfo = {
		"Key ID": key.key_id,
		"Project ID": `\`${projectId}\``,
		Description: key.description || "*No description provided*",
		Context: key.context || "*No context specified*",
	};
	lines.push(formatHeading("Core Identification", 2));
	lines.push(formatBulletList(coreInfo));
	lines.push("");

	// Platform-specific key names
	lines.push(formatHeading("Platform-Specific Key Names", 2));
	lines.push("");
	lines.push(formatPlatformObject(key.key_name));
	lines.push("");

	// Platform-specific filenames
	lines.push(formatHeading("Platform-Specific Filenames", 2));
	lines.push("");
	lines.push(formatPlatformObject(key.filenames));
	lines.push("");

	// Platform assignments
	lines.push(formatHeading("Platform Assignments", 2));
	lines.push("");
	if (key.platforms && key.platforms.length > 0) {
		lines.push(`**Assigned Platforms:** ${key.platforms.length}`);
		lines.push("");
		for (const platform of key.platforms) {
			lines.push(`- **${platform.toUpperCase()}** - Active on this platform`);
		}
	} else {
		lines.push(
			"*No platforms assigned - this key is not targeted to any specific platform*",
		);
	}
	lines.push("");

	// Tags and organization
	lines.push(formatHeading("Tags and Organization", 2));
	lines.push("");
	if (key.tags && key.tags.length > 0) {
		lines.push(`**Total Tags:** ${key.tags.length}`);
		lines.push("");
		for (const tag of key.tags) {
			lines.push(`- \`${tag}\``);
		}
	} else {
		lines.push(
			"*No tags assigned - consider adding tags for better organization*",
		);
	}
	lines.push("");

	// Content specifications
	const contentInfo = {
		"Character Limit":
			key.char_limit > 0 ? `${key.char_limit} characters` : "No limit set",
		"Base Word Count":
			key.base_words > 0 ? `${key.base_words} words` : "Not calculated",
		"Supports Pluralization": key.is_plural ? "Yes" : "No",
		"Plural Form Name": key.is_plural ? `\`${key.plural_name}\`` : "Not set",
	};

	lines.push(formatHeading("Content Specifications", 2));
	lines.push(formatBulletList(contentInfo));
	lines.push("");

	// Status and visibility
	const statusInfo = {
		Visibility: key.is_hidden
			? "🔒 Hidden from translators"
			: "👁️ Visible to translators",
		"Archive Status": key.is_archived ? "📦 Archived (inactive)" : "✅ Active",
	};
	lines.push(formatHeading("Status and Visibility", 2));
	lines.push(formatBulletList(statusInfo));
	lines.push("");

	// Timeline information
	const timelineInfo = {
		Created: `${key.created_at} (${new Date(key.created_at).toLocaleDateString()})`,
		"Last Modified": `${key.modified_at} (${new Date(key.modified_at).toLocaleDateString()})`,
		"Translations Last Modified": `${key.translations_modified_at} (${new Date(key.translations_modified_at).toLocaleDateString()})`,
	};
	lines.push(formatHeading("Timeline Information", 2));
	lines.push(formatBulletList(timelineInfo));
	lines.push("");

	if (key.custom_attributes) {
		// Custom attributes
		lines.push(formatHeading("Custom Attributes", 2));
		lines.push("");
		try {
			const parsed = JSON.parse(key.custom_attributes);
			if (Object.keys(parsed).length > 0) {
				for (const [attrKey, attrValue] of Object.entries(parsed)) {
					lines.push(`- **${attrKey}:** ${safeStringify(attrValue)}`);
				}
			} else {
				lines.push("*No custom attributes defined*");
			}
		} catch {
			lines.push(`Raw value: \`${key.custom_attributes}\``);
		}
		lines.push("");
	}

	if (key.translations && key.translations.length > 0) {
		// Translation data (if included)
		lines.push(formatHeading("Translation Status", 2));
		lines.push("");
		lines.push(`**Total Languages:** ${key.translations.length}`);
		lines.push("");

		// Translation statistics
		const reviewedCount = key.translations.filter((t) => t.is_reviewed).length;
		const unverifiedCount = key.translations.filter(
			(t) => t.is_unverified,
		).length;
		const emptyCount = key.translations.filter(
			(t) => !t.translation || t.translation.trim() === "",
		).length;

		const translationStats = {
			Reviewed: `${reviewedCount}/${key.translations.length} (${formatPercentage(reviewedCount, key.translations.length)})`,
			Unverified: `${unverifiedCount}/${key.translations.length} (${formatPercentage(unverifiedCount, key.translations.length)})`,
			"Empty/Missing": `${emptyCount}/${key.translations.length} (${formatPercentage(emptyCount, key.translations.length)})`,
		};
		lines.push(formatHeading("Translation Statistics", 3));
		lines.push(formatBulletList(translationStats));
		lines.push("");

		// Translation details table
		lines.push(formatHeading("Translation Details", 3));
		lines.push("");

		const translationData = key.translations.map((translation) => ({
			language: translation.language_iso || "Unknown",
			translation: translation.translation || "*Empty*",
			status: getTranslationStatus(translation),
			wordCount: translation.words || 0,
			lastModified: translation.modified_at
				? new Date(translation.modified_at).toLocaleDateString()
				: "Not set",
		}));

		const translationTable = formatTable(translationData, [
			{ key: "language", header: "Language" },
			{ key: "translation", header: "Translation", maxWidth: 60 },
			{ key: "status", header: "Status" },
			{ key: "wordCount", header: "Word Count" },
			{ key: "lastModified", header: "Last Modified" },
		]);

		lines.push(translationTable);
		lines.push("");
	} else {
		lines.push(formatHeading("Translation Status", 2));
		lines.push(
			"*No translation data included in this response. Use includeTranslations parameter to fetch translation details.*",
		);
		lines.push("");
	}

	// Comments summary
	lines.push(formatHeading("Comments and Collaboration", 2));
	lines.push("");
	if (key.comments && key.comments.length > 0) {
		lines.push(`**Total Comments:** ${key.comments.length}`);
		lines.push("");
		for (let i = 0; i < Math.min(key.comments.length, 5); i++) {
			const comment = key.comments[i];
			const commentDate = comment.added_at
				? new Date(comment.added_at).toLocaleDateString()
				: "Unknown date";
			const commentText = comment.comment
				? formatTruncated(comment.comment, 100)
				: "*Empty comment*";
			lines.push(`**Comment ${i + 1}** (${commentDate}): ${commentText}`);
			lines.push("");
		}
		if (key.comments.length > 5) {
			lines.push(`*... and ${key.comments.length - 5} more comments*`);
			lines.push("");
		}
	} else {
		lines.push("*No comments on this key yet*");
		lines.push("");
	}

	// Screenshots summary
	lines.push(formatHeading("Visual Context", 2));
	lines.push("");
	if (key.screenshots && key.screenshots.length > 0) {
		lines.push(`**Total Screenshots:** ${key.screenshots.length}`);
		lines.push("");
		for (let i = 0; i < Math.min(key.screenshots.length, 3); i++) {
			const screenshot = key.screenshots[i];
			const title = screenshot.title || `Screenshot ${i + 1}`;
			const description = screenshot.description || "No description";
			lines.push(`**${title}:** ${description}`);
			lines.push("");
		}
		if (key.screenshots.length > 3) {
			lines.push(`*... and ${key.screenshots.length - 3} more screenshots*`);
			lines.push("");
		}
	} else {
		lines.push(
			"*No screenshots attached - consider adding visual context for better translations*",
		);
		lines.push("");
	}

	// Summary for LLM reasoning
	lines.push(formatHeading("Summary for Analysis", 2));
	lines.push("**Key Characteristics:**");
	const summaryStats = [
		`${key.platforms?.length || 0} platform(s) targeted`,
		`${key.translations?.length || 0} language(s) configured`,
		`${key.tags?.length || 0} organizational tag(s)`,
		`${key.comments?.length || 0} collaboration comment(s)`,
		`${key.screenshots?.length || 0} visual context item(s)`,
		`Content status: ${key.is_archived ? "Archived" : "Active"} ${key.is_hidden ? "(Hidden)" : "(Visible)"}`,
	];

	for (const stat of summaryStats) {
		lines.push(`- ${stat}`);
	}

	if (key.translations && key.translations.length > 0) {
		const completionRate = Math.round(
			(key.translations.filter(
				(t) => t.translation && t.translation.trim() !== "",
			).length /
				key.translations.length) *
				100,
		);
		lines.push(`- Translation completion: ${completionRate}%`);
	}
	lines.push("");

	lines.push(formatFooter("Key details retrieved"));

	return lines.join("\n");
}

/**
 * @function formatCreateKeysResult
 * @description Formats the result of a bulk key creation operation
 * @memberof KeysFormatter
 * @param {any} response - The raw response from the Lokalise Keys API create operation
 * @param {string} projectId - The project ID for context
 * @returns {string} Formatted Markdown string containing the creation results
 */
export function formatCreateKeysResult(
	response: BulkResult<Key>,
	projectId: string,
): string {
	const createdKeys = response.items || [];
	const errors = response.errors || [];

	const lines: string[] = [];
	lines.push(formatHeading("Keys Creation Results", 1));
	lines.push("");
	lines.push(`**Project ID:** \`${projectId}\``);
	lines.push("");

	// Summary
	const summaryInfo = {
		"Successfully Created": `${createdKeys.length} keys`,
		Errors: errors.length,
		"Total Requested": createdKeys.length + errors.length,
	};
	lines.push(formatHeading("Summary", 2));
	lines.push(formatBulletList(summaryInfo));
	lines.push("");

	// Successfully created keys
	if (createdKeys.length > 0) {
		lines.push(formatHeading("✅ Successfully Created Keys", 2));
		lines.push("");

		const tableData = createdKeys.map((key) => ({
			keyId: key.key_id || "N/A",
			keyName: key.key_name || "Unnamed",
			platforms: formatSafeArray(key.platforms),
		}));

		const table = formatTable(tableData, [
			{ key: "keyId", header: "Key ID" },
			{ key: "keyName", header: "Key Name", formatter: (v) => `\`${v}\`` },
			{ key: "platforms", header: "Platforms" },
		]);

		lines.push(table);
		lines.push("");
	}

	// Errors
	lines.push(
		formatErrorList(
			errors.map((e) => ({
				...e,
				code: e.code !== undefined ? String(e.code) : undefined,
			})),
		),
	);

	lines.push(formatFooter("Keys creation completed"));

	return lines.join("\n");
}

/**
 * @function formatUpdateKeyResult
 * @description Formats the result of a key update operation
 * @memberof KeysFormatter
 * @param {Key} key - The updated key object from Lokalise API
 * @param {string} projectId - The project ID for context
 * @returns {string} Formatted Markdown string containing the update results
 */
export function formatUpdateKeyResult(key: Key, projectId: string): string {
	const lines: string[] = [];
	lines.push(formatHeading("Key Update Successful", 1));
	lines.push("");

	lines.push(
		`**Key \`${key.key_name}\` (ID: ${key.key_id}) has been updated successfully.**`,
	);
	lines.push("");

	// Updated details
	const keyInfo = {
		"Key ID": key.key_id,
		"Key Name": `\`${key.key_name}\``,
		"Project ID": `\`${projectId}\``,
		Description: key.description || "No description",
		"Last Modified": key.modified_at,
	};
	lines.push(formatHeading("Updated Key Details", 2));
	lines.push(formatBulletList(keyInfo));
	lines.push("");

	// Platforms
	lines.push(formatHeading("Platforms", 3));
	if (key.platforms && key.platforms.length > 0) {
		for (const platform of key.platforms) {
			lines.push(`- ${platform}`);
		}
	} else {
		lines.push("*No platforms specified*");
	}
	lines.push("");

	// Tags
	lines.push(formatHeading("Tags", 3));
	if (key.tags && key.tags.length > 0) {
		for (const tag of key.tags) {
			lines.push(`- \`${tag}\``);
		}
	} else {
		lines.push("*No tags assigned*");
	}
	lines.push("");

	lines.push(formatFooter("Key updated"));

	return lines.join("\n");
}

/**
 * @function formatDeleteKeyResult
 * @description Formats the result of a key deletion operation
 * @memberof KeysFormatter
 * @param {any} response - The raw response from the Lokalise Keys API delete operation
 * @param {string} projectId - The project ID for context
 * @param {number} keyId - The deleted key ID
 * @returns {string} Formatted Markdown string containing the deletion confirmation
 */
export function formatDeleteKeyResult(
	response: KeyDeleted,
	projectId: string,
	keyId: number,
): string {
	const lines: string[] = [];
	lines.push(formatHeading("Key Deletion Successful", 1));
	lines.push("");

	lines.push(
		`**Key with ID ${keyId} has been successfully deleted from project \`${projectId}\`.**`,
	);
	lines.push("");

	const deletionInfo = {
		"Deleted Key ID": keyId,
		"Project ID": `\`${projectId}\``,
		"Deletion Time": new Date().toISOString(),
		Status: response.key_removed ? "✅ Confirmed removed" : "Processing",
	};
	lines.push(formatHeading("Details", 2));
	lines.push(formatBulletList(deletionInfo));
	lines.push("");

	lines.push(
		"> **Note:** This action cannot be undone. All translations associated with this key have also been deleted.",
	);
	lines.push("");

	lines.push(formatFooter("Key deleted"));

	return lines.join("\n");
}

/**
 * @function formatBulkUpdateKeysResult
 * @description Formats the result of a bulk key update operation
 * @memberof KeysFormatter
 * @param {any} response - The raw response from the Lokalise Keys API bulk update operation
 * @param {string} projectId - The project ID for context
 * @returns {string} Formatted Markdown string containing the bulk update results
 */
export function formatBulkUpdateKeysResult(
	response: BulkResult<Key>,
	projectId: string,
): string {
	const updatedKeys = response.items || [];
	const errors = response.errors || [];

	const lines: string[] = [];
	lines.push(formatHeading("Bulk Keys Update Results", 1));
	lines.push("");
	lines.push(`**Project ID:** \`${projectId}\``);
	lines.push("");

	// Summary
	const summaryInfo = {
		"Successfully Updated": `${updatedKeys.length} keys`,
		Errors: errors.length,
		"Total Requested": updatedKeys.length + errors.length,
	};
	lines.push(formatHeading("Summary", 2));
	lines.push(formatBulletList(summaryInfo));
	lines.push("");

	// Successfully updated keys
	if (updatedKeys.length > 0) {
		lines.push(formatHeading("✅ Successfully Updated Keys", 2));
		lines.push("");

		const tableData = updatedKeys.map((key) => ({
			keyId: key.key_id || "N/A",
			keyName: key.key_name || "Unnamed",
			lastModified: key.modified_at || "Unknown",
		}));

		const table = formatTable(tableData, [
			{ key: "keyId", header: "Key ID" },
			{ key: "keyName", header: "Key Name", formatter: (v) => `\`${v}\`` },
			{ key: "lastModified", header: "Last Modified" },
		]);

		lines.push(table);
		lines.push("");
	}

	// Errors
	lines.push(
		formatErrorList(
			errors.map((e) => ({
				...e,
				code: e.code !== undefined ? String(e.code) : undefined,
			})),
		),
	);

	lines.push(formatFooter("Bulk update completed"));

	return lines.join("\n");
}

/**
 * @function formatBulkDeleteKeysResult
 * @description Formats the result of a bulk key deletion operation
 * @memberof KeysFormatter
 * @param {any} response - The raw response from the Lokalise Keys API bulk delete operation
 * @param {string} projectId - The project ID for context
 * @param {number} requestedCount - The number of keys requested to be deleted
 * @returns {string} Formatted Markdown string containing the bulk deletion results
 */
export function formatBulkDeleteKeysResult(
	response: KeysBulkDeleted,
	projectId: string,
	requestedCount: number,
): string {
	const lines: string[] = [];
	lines.push(formatHeading("Bulk Keys Deletion Successful", 1));
	lines.push("");

	lines.push(
		`**${requestedCount} keys have been successfully deleted from project \`${projectId}\`.**`,
	);
	lines.push("");

	const deletionInfo = {
		"Deleted Keys Count": requestedCount,
		"Project ID": `\`${projectId}\``,
		"Deletion Time": new Date().toISOString(),
		Status: response.keys_removed
			? "✅ All keys confirmed removed"
			: "Processing",
	};
	lines.push(formatHeading("Details", 2));
	lines.push(formatBulletList(deletionInfo));
	lines.push("");

	lines.push(
		"> **Note:** This action cannot be undone. All translations associated with these keys have also been deleted.",
	);
	lines.push("");

	lines.push(formatFooter("Bulk deletion completed"));

	return lines.join("\n");
}

// Helper functions

function getKeyStatus(key: Key): string {
	const statusParts: string[] = [];
	if (key.is_hidden) statusParts.push("🔒Hidden");
	if (key.is_archived) statusParts.push("📦Archived");
	if (key.is_plural) statusParts.push("🔢Plural");
	if (key.comments && key.comments.length > 0)
		statusParts.push(`💬${key.comments.length}`);
	if (key.screenshots && key.screenshots.length > 0)
		statusParts.push(`📷${key.screenshots.length}`);
	return statusParts.length > 0 ? statusParts.join(" ") : "✅Standard";
}

function getTranslationStatus(translation: unknown): string {
	if (!translation || typeof translation !== "object") {
		return "❌ Missing";
	}

	if (
		"translation" in translation &&
		typeof translation.translation === "string" &&
		translation.translation.trim() !== ""
	) {
		return "✅ Reviewed";
	}

	if ("is_reviewed" in translation && translation.is_reviewed) {
		return "✅ Reviewed";
	}

	if ("translation" in translation && translation.translation === "") {
		return "❌ Empty";
	}

	if ("is_unverified" in translation && translation.is_unverified) {
		return "⚠️ Unverified";
	}

	return "⏳ Pending Review";
}
