import { FormatterPlugin, PluginContext, AnalysisResult, OutputSection, Logger } from '../../types'; export class HtmlFormatter implements FormatterPlugin { readonly name = 'html-formatter'; readonly version = '1.0.0'; readonly description = 'Formats analysis results as interactive HTML report'; readonly outputFormat = 'html' as const; private logger!: Logger; async initialize(context: PluginContext): Promise { this.logger = context.logger; this.logger.debug('HTML formatter initialized'); } async format(result: AnalysisResult, sections: OutputSection[]): Promise { const timestamp = new Date().toLocaleString(); const { summary } = result; return ` Translation Analysis Report

🔍 Translation Analysis Report

Generated on ${timestamp} | Source: ${result.config.srcPath} | Locales: ${result.config.localesPath}
${summary.totalTranslations}
Total Translations
${summary.coverage}%
Coverage
${summary.totalMissingKeys}
Missing Keys
${summary.totalUnusedKeys}
Unused Keys

Coverage Overview

Used ${summary.totalUsedKeys} out of ${summary.totalTranslations} available translations (${summary.coverage}% coverage)

${sections.includes('missing') ? this.generateMissingKeysSection(result) : ''} ${sections.includes('unused') ? this.generateUnusedKeysSection(result) : ''} ${sections.includes('dynamicPatterns') ? this.generateDynamicPatternsSection(result) : ''} ${sections.includes('usedKeys') ? this.generateUsedKeysSection(result) : ''}
`; } private generateMissingKeysSection(result: AnalysisResult): string { if (!result.missingKeys || result.missingKeys.length === 0) { return '

🎉 No missing keys found!

'; } const keysHtml = result.missingKeys.map(key => `
❌ ${key.key}
📍 ${key.file}:${key.line}${key.column ? `:${key.column}` : ''}
${key.context ? `${key.context}` : ''}
`).join(''); return `
${keysHtml}
`; } private generateUnusedKeysSection(result: AnalysisResult): string { if (!result.unusedKeys || result.unusedKeys.length === 0) { return '

🎉 No unused keys found!

'; } const keysHtml = result.unusedKeys.map(key => `
🗑️ ${key}
Safe to remove - not found in source code
`).join(''); return `
${keysHtml}
`; } private generateDynamicPatternsSection(result: AnalysisResult): string { if (!result.dynamicPatterns || result.dynamicPatterns.length === 0) { return '

No dynamic patterns detected.

'; } const patternsHtml = result.dynamicPatterns.map(pattern => `
🔄 ${pattern.pattern}
${pattern.matches.length} occurrences found
${pattern.matches.slice(0, 5).map(match => `${match}`).join('')} ${pattern.matches.length > 5 ? `... and ${pattern.matches.length - 5} more` : ''}
`).join(''); return `
${patternsHtml}
`; } private generateUsedKeysSection(result: AnalysisResult): string { if (!result.usedKeys || result.usedKeys.length === 0) { return '

No used keys found.

'; } const keysHtml = result.usedKeys.slice(0, 50).map(key => `
✅ ${key.key}
📍 ${key.file}:${key.line}${key.column ? `:${key.column}` : ''}
${key.context ? `${key.context}` : ''}
`).join(''); return `
${keysHtml} ${result.usedKeys.length > 50 ? `

Showing first 50 of ${result.usedKeys.length} used keys

` : ''}
`; } }