/**
 * @file wally-report.js
 * @description Report processing for Wally Monitor — processAxeResults,
 *              calculateWCAGScore, determineConformanceLevel.
 *              Uses WallyMonitor.Stats.collectElementStats and
 *              WallyMonitor.Utils.escapeHtml internally.
 * @module WallyMonitor.Report
 */
window.WallyMonitor = window.WallyMonitor || {};

(function($) {
    'use strict';

    WallyMonitor.Report = WallyMonitor.Report || {};

    /**
     * Processa os resultados brutos do Axe em um formato de relatório
     * @param {Array} violations - Array de violações do axe-core + custom rules
     * @param {Document|null} documentContext - Documento para coleta de estatísticas (pode ser null)
     * @returns {Object} Relatório processado com summary e violations
     */
    WallyMonitor.Report.processAxeResults = function(violations, documentContext) {
        var escapeHtml = WallyMonitor.Utils.escapeHtml;

        const report = {
            summary: {
                totalProblems: 0,
                rulesViolated: [],
                byImpact: { critical: 0, serious: 0, moderate: 0, minor: 0 },
                wcagLevels: { A: 0, AA: 0, AAA: 0 },
                wpBlocks: { images: 0, buttons: 0, headings: 0, links: 0, other: 0 },
                // NOVO: Estatísticas de elementos testados
                elementsStats: {
                    totalImages: 0,
                    imagesWithAlt: 0,
                    totalLinks: 0,
                    linksWithText: 0,
                    totalButtons: 0,
                    buttonsWithLabel: 0,
                    totalFormFields: 0,
                    formFieldsWithLabel: 0,
                    totalHeadings: 0,
                    headingsCorrect: 0,
                    totalTables: 0,
                    tablesAccessible: 0,
                    totalVideos: 0,
                    videosWithCaptions: 0
                }
            },
            violations: []
        };

        // NOVO: Coleta estatísticas de elementos corretos se temos contexto do documento
        if (documentContext) {
            WallyMonitor.Stats.collectElementStats(documentContext, report.summary.elementsStats, violations);
        }

        const uniqueViolations = {};

        violations.forEach(violation => {
            // Mapeia problemas por nível WCAG (filtra apenas regras WCAG)
            if (violation.tags) {
                // Verifica se tem pelo menos uma tag WCAG
                const hasWCAGTag = violation.tags.some(tag => 
                    tag.startsWith('wcag2') || 
                    tag.startsWith('best-practice') ||
                    tag === 'cat.name-role-value' ||
                    tag === 'cat.semantics' ||
                    tag === 'cat.structure' ||
                    tag === 'cat.text-alternatives' ||
                    tag === 'cat.color' ||
                    tag === 'cat.keyboard' ||
                    tag === 'cat.sensory-and-visual-cues' ||
                    tag === 'cat.tables' ||
                    tag === 'cat.forms' ||
                    tag === 'cat.time-and-media'
                );
                
                // Se não tem nenhuma tag relevante, ignora esta violação
                if (!hasWCAGTag && !violation.id.startsWith('custom-')) {
                    return;
                }
                
                if (violation.tags.includes('wcag2a') || violation.tags.includes('wcag21a') || violation.tags.includes('wcag22a')) {
                    report.summary.wcagLevels.A += violation.nodes.length;
                }
                if (violation.tags.includes('wcag2aa') || violation.tags.includes('wcag21aa') || violation.tags.includes('wcag22aa')) {
                    report.summary.wcagLevels.AA += violation.nodes.length;
                }
                if (violation.tags.includes('wcag2aaa') || violation.tags.includes('wcag21aaa') || violation.tags.includes('wcag22aaa')) {
                    report.summary.wcagLevels.AAA += violation.nodes.length;
                }
            }
            
            // Adiciona ao relatório ANTES de contar (será recontado depois da deduplicação)
            if (report.summary.rulesViolated.indexOf(violation.id) === -1) {
                report.summary.rulesViolated.push(violation.id);
            }

            if (!uniqueViolations[violation.id]) {
                uniqueViolations[violation.id] = { 
                    ...violation, 
                    nodes: [],
                    _seenSelectors: {} // Objeto auxiliar para rastrear seletores únicos
                };
            }
            
            // Adiciona apenas nodes únicos (baseado no selector)
            violation.nodes.forEach(node => {
                const selector = JSON.stringify(node.target);
                if (!uniqueViolations[violation.id]._seenSelectors[selector]) {
                    uniqueViolations[violation.id]._seenSelectors[selector] = true;
                    uniqueViolations[violation.id].nodes.push(node);
                }
            });
        });

        // Remove o Set auxiliar e RECONTA problemas com nodes deduplicados
        report.violations = Object.values(uniqueViolations).map(v => {
            const { _seenSelectors, ...violation } = v;
            
            // Agora conta DEPOIS da deduplicação
            report.summary.byImpact[violation.impact] += violation.nodes.length;
            report.summary.totalProblems += violation.nodes.length;
            
            // Conta problemas em blocos WordPress específicos
            violation.nodes.forEach(node => {
                const selector = node.target[0] || '';
                if (selector.includes('wp-block-image') || selector.includes('wp-image-')) {
                    report.summary.wpBlocks.images++;
                } else if (selector.includes('wp-block-button') || selector.includes('wp-element-button')) {
                    report.summary.wpBlocks.buttons++;
                } else if (selector.includes('wp-block-heading')) {
                    report.summary.wpBlocks.headings++;
                } else if (selector.includes('wp-block') && selector.match(/a\[|a\./)) {
                    report.summary.wpBlocks.links++;
                } else if (selector.includes('wp-block-')) {
                    report.summary.wpBlocks.other++;
                }
            });
            
            return violation;
        });
        
        // Calcula o score baseado em padrões WCAG oficiais (agora considera elementos corretos)
        report.summary.score = WallyMonitor.Report.calculateWCAGScore(report.summary);
        report.summary.conformanceLevel = WallyMonitor.Report.determineConformanceLevel(report.summary);

        return report;
    };

    /**
     * Calcula o score de acessibilidade baseado em critérios WCAG
     * Metodologia híbrida: considera elementos corretos + penalização por problemas
     * @param {Object} summary - Sumário do relatório
     * @returns {number} Score de 0 a 100
     */
    WallyMonitor.Report.calculateWCAGScore = function(summary) {
        // Pesos por impacto (reduzidos para não penalizar excessivamente)
        const impactWeights = {
            critical: 5,   // Bloqueadores totais - violações de Nível A críticas
            serious: 3,    // Grandes barreiras - violações graves de A/AA
            moderate: 1.5, // Barreiras significativas - violações moderadas de AA
            minor: 0.5     // Pequenas barreiras - violações de AAA ou best practices
        };

        // PARTE 1: Score baseado em taxa de conformidade (elementos corretos)
        let conformanceScore = 100;
        
        if (summary.elementsStats) {
            const stats = summary.elementsStats;
            let totalScore = 0;
            let categoryCount = 0;
            
            // Calcula score por categoria (média de porcentagens, não soma ponderada)
            const categories = [
                { total: stats.totalImages, correct: stats.imagesWithAlt, name: 'images' },
                { total: stats.totalFormFields, correct: stats.formFieldsWithLabel, name: 'forms' },
                { total: stats.totalLinks, correct: stats.linksWithText, name: 'links' },
                { total: stats.totalButtons, correct: stats.buttonsWithLabel, name: 'buttons' },
                { total: stats.totalHeadings, correct: stats.headingsCorrect, name: 'headings' },
                { total: stats.totalTables, correct: stats.tablesAccessible, name: 'tables' },
                { total: stats.totalVideos, correct: stats.videosWithCaptions, name: 'videos' }
            ];
            
            categories.forEach(cat => {
                if (cat.total > 0) {
                    const categoryScore = (cat.correct / cat.total) * 100;
                    totalScore += categoryScore;
                    categoryCount++;
                }
            });
            
            if (categoryCount > 0) {
                // Média das categorias existentes
                conformanceScore = totalScore / categoryCount;
            }
        }

        // PARTE 2: Penalização por problemas detectados
        let penaltyPoints = 0;
        penaltyPoints += summary.byImpact.critical * impactWeights.critical;
        penaltyPoints += summary.byImpact.serious * impactWeights.serious;
        penaltyPoints += summary.byImpact.moderate * impactWeights.moderate;
        penaltyPoints += summary.byImpact.minor * impactWeights.minor;

        // Score de penalização
        // Cada ponto de penalização reduz o score
        let penaltyScore = Math.max(0, 100 - penaltyPoints);

        // PARTE 3: Score híbrido (75% conformidade + 25% penalização)
        // Valoriza mais a conformidade positiva do que as violações pontuais
        let finalScore;
        if (summary.elementsStats && 
            (summary.elementsStats.totalImages > 0 || 
             summary.elementsStats.totalLinks > 0 || 
             summary.elementsStats.totalFormFields > 0)) {
            // Híbrido: prioriza elementos corretos
            finalScore = (conformanceScore * 0.75) + (penaltyScore * 0.25);
        } else {
            // Fallback para modo antigo (só penalização)
            finalScore = penaltyScore;
        }

        // Bônus para sites sem problemas críticos ou sérios
        if (summary.byImpact.critical === 0 && summary.byImpact.serious === 0) {
            finalScore = Math.min(100, finalScore + 5);
        }

        // Penalidade extra apenas para sites com MUITOS problemas críticos
        if (summary.byImpact.critical >= 10) {
            finalScore = Math.max(0, finalScore - 10);
        }

        // Garantir que o score está entre 0 e 100
        finalScore = Math.max(0, Math.min(100, finalScore));

        return Math.round(finalScore);
    };

    /**
     * Determina o nível de conformidade WCAG
     * Retorna: 'Non-Conformant', 'Partial A', 'Level A', 'Partial AA', 'Level AA', 'Partial AAA', 'Level AAA'
     * @param {Object} summary - Sumário do relatório
     * @returns {string} Nível de conformidade
     */
    WallyMonitor.Report.determineConformanceLevel = function(summary) {
        // WCAG exige conformidade total em um nível para ser considerado conforme
        // Qualquer violação de um nível impede a conformidade completa
        
        if (summary.wcagLevels.A === 0 && summary.wcagLevels.AA === 0 && summary.wcagLevels.AAA === 0) {
            if (summary.totalProblems === 0) {
                return 'Level AAA';
            }
            // Problems exist but none have WCAG level tags — cannot determine conformance.
            return 'Indeterminate';
        }

        if (summary.wcagLevels.A > 0) {
            // Violações de Nível A impedem qualquer conformidade
            return summary.byImpact.critical > 0 ? 'Non-Conformant' : 'Partial A';
        }

        if (summary.wcagLevels.AA > 0) {
            // Sem violações A, mas com violações AA
            return 'Partial AA (Level A)';
        }

        if (summary.wcagLevels.AAA > 0) {
            // Sem violações A e AA, mas com violações AAA
            return 'Partial AAA (Level AA)';
        }

        return 'Level AA';
    };

})(jQuery);
