/**
 * Real-time SEO Content Analyzer - Yoast Style
 * Analyzes content readability, keyword density, and structure
 */

class SEOContentAnalyzer {
    constructor() {
        this.focusKeyword = '';
        this.content = '';
        this.title = '';
        this.metaDescription = '';
    }

    /**
     * Analyze all SEO metrics
     */
    analyzeContent(content, focusKeyword, title, metaDescription) {
        this.content = content;
        this.focusKeyword = focusKeyword.toLowerCase();
        this.title = title;
        this.metaDescription = metaDescription;

        return {
            readability: this.analyzeReadability(),
            keywords: this.analyzeKeywords(),
            structure: this.analyzeStructure(),
            contentLength: this.analyzeContentLength(),
            seoScore: this.calculateSEOScore()
        };
    }

    /**
     * Analyze readability using Flesch-Kincaid formula
     */
    analyzeReadability() {
        const text = this.stripHtml(this.content);
        const sentences = this.countSentences(text);
        const words = this.countWords(text);
        const syllables = this.countSyllables(text);
        const paragraphs = this.countParagraphs(this.content);

        if (words === 0) {
            return { score: 0, grade: 'No content', issues: [] };
        }

        const fleschReading = this.fleschReadingEase(sentences, words, syllables);
        const grade = this.getGradeLevel(fleschReading);
        const issues = [];

        // Check for wall of text (paragraphs > 150 words)
        const avgWordsPerParagraph = words / Math.max(paragraphs, 1);
        if (avgWordsPerParagraph > 150) {
            issues.push({
                severity: 'warning',
                message: '⚠️ Long paragraphs detected. Break into smaller chunks.',
                details: `Average paragraph length: ${Math.round(avgWordsPerParagraph)} words`
            });
        }

        // Check average sentence length (optimal: 15-20 words)
        const avgSentenceLength = words / Math.max(sentences, 1);
        if (avgSentenceLength > 20) {
            issues.push({
                severity: 'warning',
                message: '⚠️ Sentences are too long. Consider shortening them.',
                details: `Average: ${Math.round(avgSentenceLength)} words per sentence`
            });
        }

        if (fleschReading < 30) {
            issues.push({
                severity: 'error',
                message: '🔴 Content is too difficult to read.',
                details: 'Simplify language and use shorter sentences.'
            });
        } else if (fleschReading < 60) {
            issues.push({
                severity: 'warning',
                message: '🟡 Content readability could be improved.',
                details: 'Consider simplifying some sentences.'
            });
        } else {
            issues.push({
                severity: 'success',
                message: '🟢 Readability is excellent.',
                details: `Flesch Reading Ease: ${Math.round(fleschReading)}`
            });
        }

        return {
            score: Math.round(fleschReading),
            grade: grade,
            metrics: {
                sentences: sentences,
                words: words,
                syllables: syllables,
                paragraphs: paragraphs,
                avgSentenceLength: Math.round(avgSentenceLength * 10) / 10,
                avgWordsPerParagraph: Math.round(avgWordsPerParagraph * 10) / 10
            },
            issues: issues
        };
    }

    /**
     * Analyze keyword usage
     */
    analyzeKeywords() {
        if (!this.focusKeyword) {
            return { score: 0, issues: [{ severity: 'error', message: '🔴 No focus keyword set' }] };
        }

        const text = this.stripHtml(this.content).toLowerCase();
        const words = this.countWords(text);
        const keywords = text.match(new RegExp(`\\b${this.escapeRegex(this.focusKeyword)}\\b`, 'g')) || [];
        const keywordCount = keywords.length;
        const keywordDensity = (keywordCount / words) * 100;
        const firstWords = text.split(/\s+/).slice(0, 100).join(' ');
        const inFirstHundred = firstWords.includes(this.focusKeyword);

        const issues = [];

        // Check if keyword is in first 100 words
        if (!inFirstHundred) {
            issues.push({
                severity: 'warning',
                message: '🟡 Focus keyword not in first 100 words.',
                details: 'Place your main keyword early in the content.'
            });
        } else {
            issues.push({
                severity: 'success',
                message: '🟢 Focus keyword appears early.',
                details: ''
            });
        }

        // Check keyword density (optimal: 1-3%)
        if (keywordDensity === 0) {
            issues.push({
                severity: 'error',
                message: '🔴 Focus keyword not found in content.',
                details: 'Add your keyword naturally to the content.'
            });
        } else if (keywordDensity > 3) {
            issues.push({
                severity: 'error',
                message: '🔴 Keyword stuffing detected!',
                details: `Keyword density: ${Math.round(keywordDensity * 100) / 100}% (Max: 3%)`
            });
        } else if (keywordDensity < 0.5) {
            issues.push({
                severity: 'warning',
                message: '🟡 Keyword density too low.',
                details: `Current: ${Math.round(keywordDensity * 100) / 100}% (Optimal: 1-3%)`
            });
        } else {
            issues.push({
                severity: 'success',
                message: '🟢 Keyword density is optimal.',
                details: `Density: ${Math.round(keywordDensity * 100) / 100}%`
            });
        }

        // Check title and meta description
        const titleHasKeyword = this.title.toLowerCase().includes(this.focusKeyword);
        const metaHasKeyword = this.metaDescription.toLowerCase().includes(this.focusKeyword);

        if (!titleHasKeyword) {
            issues.push({
                severity: 'warning',
                message: '🟡 Keyword not in page title.',
                details: 'Add your focus keyword to the SEO title.'
            });
        } else {
            issues.push({
                severity: 'success',
                message: '🟢 Keyword in page title.',
                details: ''
            });
        }

        if (!metaHasKeyword) {
            issues.push({
                severity: 'info',
                message: 'ℹ️ Keyword not in meta description.',
                details: 'Consider adding it for better CTR.'
            });
        }

        return {
            keyword: this.focusKeyword,
            count: keywordCount,
            density: Math.round(keywordDensity * 100) / 100,
            inFirstHundred: inFirstHundred,
            inTitle: titleHasKeyword,
            inMetaDesc: metaHasKeyword,
            score: this.getKeywordScore(keywordDensity, keywordCount > 0),
            issues: issues
        };
    }

    /**
     * Analyze content structure (headings, lists, etc.)
     */
    analyzeStructure() {
        const html = this.content;
        const h1Count = (html.match(/<h1[^>]*>/gi) || []).length;
        const h2Count = (html.match(/<h2[^>]*>/gi) || []).length;
        const h3Count = (html.match(/<h3[^>]*>/gi) || []).length;
        const imageCount = (html.match(/<img[^>]*>/gi) || []).length;
        const imagesWithoutAlt = (html.match(/<img(?!.*alt=)[^>]*>/gi) || []).length;
        const listCount = (html.match(/<ul[^>]*>|<ol[^>]*>/gi) || []).length;

        const issues = [];

        // H1 check - should have exactly one
        if (h1Count === 0) {
            issues.push({
                severity: 'error',
                message: '🔴 Missing H1 heading.',
                details: 'Every page should have exactly one H1 tag.',
                traffic: 'red'
            });
        } else if (h1Count > 1) {
            issues.push({
                severity: 'error',
                message: '🔴 Multiple H1 headings found.',
                details: `Found ${h1Count}. Use only one H1 per page.`,
                traffic: 'red'
            });
        } else {
            issues.push({
                severity: 'success',
                message: '🟢 Perfect H1 structure.',
                details: '',
                traffic: 'green'
            });
        }

        // Subheadings check
        if (h2Count === 0 && this.countWords(this.stripHtml(this.content)) > 300) {
            issues.push({
                severity: 'warning',
                message: '🟡 Long content without subheadings.',
                details: 'Add H2/H3 tags to break up content.',
                traffic: 'yellow'
            });
        } else if (h2Count > 0) {
            issues.push({
                severity: 'success',
                message: '🟢 Good use of subheadings.',
                details: `H2: ${h2Count}, H3: ${h3Count}`,
                traffic: 'green'
            });
        }

        // Image optimization
        if (imageCount === 0) {
            issues.push({
                severity: 'info',
                message: 'ℹ️ No images detected.',
                details: 'Consider adding relevant images to improve engagement.'
            });
        } else if (imagesWithoutAlt > 0) {
            issues.push({
                severity: 'warning',
                message: '🟡 Missing alt text on images.',
                details: `${imagesWithoutAlt}/${imageCount} images lack alt attributes.`,
                traffic: 'yellow'
            });
        } else {
            issues.push({
                severity: 'success',
                message: '🟢 All images have alt text.',
                details: `${imageCount} optimized images`,
                traffic: 'green'
            });
        }

        return {
            h1: { count: h1Count, traffic: h1Count === 1 ? 'green' : 'red' },
            h2: { count: h2Count, traffic: h2Count > 0 ? 'green' : 'yellow' },
            h3: { count: h3Count },
            images: {
                total: imageCount,
                withoutAlt: imagesWithoutAlt,
                traffic: imagesWithoutAlt === 0 ? 'green' : 'yellow'
            },
            lists: listCount,
            score: this.getStructureScore(h1Count, h2Count, imagesWithoutAlt, imageCount),
            issues: issues
        };
    }

    /**
     * Analyze content length
     */
    analyzeContentLength() {
        const words = this.countWords(this.stripHtml(this.content));
        const titleLength = this.title.length;
        const metaLength = this.metaDescription.length;

        const issues = [];

        // Content length check (optimal: 300+ words)
        if (words < 300) {
            issues.push({
                severity: 'warning',
                message: '🟡 Content is too short.',
                details: `${words} words. Aim for at least 300 words.`,
                traffic: 'yellow'
            });
        } else if (words < 1500) {
            issues.push({
                severity: 'success',
                message: '🟢 Good content length.',
                details: `${words} words`,
                traffic: 'green'
            });
        } else {
            issues.push({
                severity: 'success',
                message: '🟢 Comprehensive content.',
                details: `${words} words - excellent depth`,
                traffic: 'green'
            });
        }

        // Title length check (optimal: 30-60 characters)
        if (titleLength < 30) {
            issues.push({
                severity: 'warning',
                message: '🟡 SEO Title is too short.',
                details: `${titleLength} chars. Aim for 30-60.`,
                traffic: 'yellow'
            });
        } else if (titleLength > 60) {
            issues.push({
                severity: 'warning',
                message: '🟡 SEO Title is too long.',
                details: `${titleLength} chars. Keep it under 60.`,
                traffic: 'yellow'
            });
        } else {
            issues.push({
                severity: 'success',
                message: '🟢 Title length is perfect.',
                details: `${titleLength} characters`,
                traffic: 'green'
            });
        }

        // Meta description check (optimal: 120-160 characters)
        if (metaLength === 0) {
            issues.push({
                severity: 'warning',
                message: '🟡 No meta description.',
                details: 'Add a meta description (120-160 chars).',
                traffic: 'yellow'
            });
        } else if (metaLength < 120) {
            issues.push({
                severity: 'warning',
                message: '🟡 Meta description is too short.',
                details: `${metaLength} chars. Aim for 120-160.`,
                traffic: 'yellow'
            });
        } else if (metaLength > 160) {
            issues.push({
                severity: 'warning',
                message: '🟡 Meta description is too long.',
                details: `${metaLength} chars. Keep it under 160.`,
                traffic: 'yellow'
            });
        } else {
            issues.push({
                severity: 'success',
                message: '🟢 Meta description is perfect.',
                details: `${metaLength} characters`,
                traffic: 'green'
            });
        }

        return {
            words: words,
            titleLength: titleLength,
            metaLength: metaLength,
            issues: issues
        };
    }

    /**
     * Calculate overall SEO score
     */
    calculateSEOScore() {
        let score = 0;
        const maxScore = 100;
        let components = 0;

        const readability = this.analyzeReadability();
        const keywords = this.analyzeKeywords();
        const structure = this.analyzeStructure();
        const contentLength = this.analyzeContentLength();

        // Readability: 25 points
        score += (readability.score / 100) * 25;
        components++;

        // Keywords: 25 points
        if (keywords.keyword) {
            score += Math.min(keywords.score, 25);
        }
        components++;

        // Structure: 25 points
        score += Math.min(structure.score, 25);
        components++;

        // Content Length: 25 points
        const lengthScore = contentLength.words >= 300 ? 25 : (contentLength.words / 300) * 25;
        score += lengthScore;
        components++;

        return Math.round(score / components);
    }

    // ============= Helper Methods =============

    stripHtml(html) {
        return html.replace(/<[^>]*>/g, '');
    }

    countWords(text) {
        return text.trim().split(/\s+/).filter(w => w.length > 0).length;
    }

    countSentences(text) {
        return text.match(/[.!?]+/g)?.length || 0;
    }

    countSyllables(text) {
        let syllableCount = 0;
        const words = text.split(/\s+/);

        words.forEach(word => {
            syllableCount += this.estimateSyllables(word);
        });

        return Math.max(syllableCount, 1);
    }

    estimateSyllables(word) {
        word = word.toLowerCase();
        let count = 0;
        let vowels = 'aeiouy';
        let previousWasVowel = false;

        for (let char of word) {
            let isVowel = vowels.includes(char);
            if (isVowel && !previousWasVowel) count++;
            previousWasVowel = isVowel;
        }

        if (word.endsWith('e')) count--;
        if (word.endsWith('le') && word.length > 2 && !vowels.includes(word[word.length - 3])) {
            count++;
        }

        return Math.max(1, count);
    }

    countParagraphs(html) {
        return (html.match(/<p[^>]*>|<div[^>]*>/gi) || []).length;
    }

    fleschReadingEase(sentences, words, syllables) {
        if (sentences === 0 || words === 0) return 0;
        return 206.835 - 1.015 * (words / sentences) - 84.6 * (syllables / words);
    }

    getGradeLevel(fleschReading) {
        if (fleschReading >= 90) return '5th Grade';
        if (fleschReading >= 80) return '6th Grade';
        if (fleschReading >= 70) return '7th Grade';
        if (fleschReading >= 60) return '8th-9th Grade';
        if (fleschReading >= 50) return '10th-12th Grade';
        if (fleschReading >= 30) return 'College';
        return 'Graduate';
    }

    escapeRegex(string) {
        return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    }

    getKeywordScore(density, hasKeyword) {
        if (!hasKeyword) return 0;
        if (density >= 1 && density <= 3) return 25;
        if (density >= 0.5 && density < 1) return 20;
        if (density > 3) return 10;
        return 15;
    }

    getStructureScore(h1, h2, imagesWithoutAlt, totalImages) {
        let score = 0;
        if (h1 === 1) score += 10;
        if (h2 > 0) score += 10;
        if (totalImages > 0 && imagesWithoutAlt === 0) score += 5;
        return score;
    }
}

// Export for use
if (typeof module !== 'undefined' && module.exports) {
    module.exports = SEOContentAnalyzer;
}
