<?php
/**
 * SEO Keyword Optimizer
 * Analyzes keyword usage, density, and optimization
 */

class KeywordOptimizer {
    
    /**
     * Analyze keyword optimization
     */
    public static function analyzeKeywords($content, $focus_keyword = '', $meta_description = '', $title = '') {
        $text = strip_tags($content);
        
        // Extract keywords
        $keywords = self::extractKeywords($text);
        
        // Calculate keyword density
        $density_report = self::calculateKeywordDensity($text);
        
        // Analyze focus keyword
        $focus_analysis = [];
        if (!empty($focus_keyword)) {
            $focus_analysis = self::analyzeFocusKeyword($text, $focus_keyword, $title, $meta_description);
        }
        
        // Get keyword suggestions
        $suggestions = self::generateKeywordSuggestions($content, $focus_keyword, $keywords);
        
        // Calculate keyword score
        $score = self::calculateKeywordScore($focus_analysis, $keywords);
        
        return [
            'score' => $score,
            'focus_keyword' => $focus_keyword,
            'focus_analysis' => $focus_analysis,
            'top_keywords' => array_slice($keywords, 0, 10),
            'keyword_density' => $density_report,
            'suggestions' => $suggestions,
            'keyword_count' => count($keywords)
        ];
    }
    
    /**
     * Extract keywords from content using word frequency
     */
    private static function extractKeywords($text) {
        // Convert to lowercase
        $text = strtolower($text);
        
        // Remove HTML and special characters
        $text = strip_tags($text);
        
        // Split into words
        $words = preg_split('/\s+/', $text, -1, PREG_SPLIT_NO_EMPTY);
        
        // Common stop words to exclude
        $stop_words = self::getStopWords();
        
        // Filter and count
        $keyword_freq = [];
        foreach ($words as $word) {
            // Remove punctuation
            $word = preg_replace('/[^\w]/', '', $word);
            
            // Skip if too short, stop word, or number
            if (strlen($word) < 4 || in_array($word, $stop_words) || is_numeric($word)) {
                continue;
            }
            
            // Count frequency
            if (isset($keyword_freq[$word])) {
                $keyword_freq[$word]++;
            } else {
                $keyword_freq[$word] = 1;
            }
        }
        
        // Sort by frequency
        arsort($keyword_freq);
        
        // Format as array of keywords
        $keywords = [];
        foreach ($keyword_freq as $word => $count) {
            $keywords[] = [
                'word' => $word,
                'frequency' => $count,
                'density' => round(($count / count($words)) * 100, 2)
            ];
        }
        
        return array_slice($keywords, 0, 50);
    }
    
    /**
     * Calculate keyword density
     */
    private static function calculateKeywordDensity($text) {
        $text = strtolower($text);
        $words = preg_split('/\s+/', $text, -1, PREG_SPLIT_NO_EMPTY);
        $total_words = count($words);
        
        $stop_words = self::getStopWords();
        $content_words = 0;
        
        foreach ($words as $word) {
            $word = preg_replace('/[^\w]/', '', $word);
            if (strlen($word) >= 4 && !in_array($word, $stop_words)) {
                $content_words++;
            }
        }
        
        return [
            'total_words' => $total_words,
            'content_words' => $content_words,
            'stop_words' => $total_words - $content_words,
            'keyword_to_stop_ratio' => $content_words > 0 ? round($content_words / ($total_words - $content_words), 2) : 0
        ];
    }
    
    /**
     * Analyze focus keyword usage
     */
    private static function analyzeFocusKeyword($text, $focus_keyword, $title = '', $meta_description = '') {
        $text_lower = strtolower($text);
        $keyword_lower = strtolower($focus_keyword);
        
        // Count occurrences
        $count = substr_count($text_lower, $keyword_lower);
        $word_count = str_word_count($text_lower);
        $density = $word_count > 0 ? round(($count / $word_count) * 100, 2) : 0;
        
        // Check presence in title
        $in_title = stripos($title, $focus_keyword) !== false;
        
        // Check presence in meta description
        $in_meta = stripos($meta_description, $focus_keyword) !== false;
        
        // Check first 100 words
        $words = explode(' ', $text_lower);
        $first_100 = implode(' ', array_slice($words, 0, 100));
        $in_first_100 = stripos($first_100, $keyword_lower) !== false;
        
        // Calculate optimization score
        $opt_score = 0;
        if ($in_title) $opt_score += 25;
        if ($in_meta) $opt_score += 20;
        if ($in_first_100) $opt_score += 20;
        if ($density > 0.5 && $density < 2.5) $opt_score += 25; // Ideal density range
        
        return [
            'focus_keyword' => $focus_keyword,
            'count' => $count,
            'density' => $density,
            'in_title' => $in_title,
            'in_meta_description' => $in_meta,
            'in_first_100_words' => $in_first_100,
            'optimization_score' => min(100, $opt_score),
            'status' => self::getKeywordStatus($count, $density, $in_title, $in_meta)
        ];
    }
    
    /**
     * Determine keyword status
     */
    private static function getKeywordStatus($count, $density, $in_title, $in_meta) {
        if ($count === 0) {
            return ['level' => 'error', 'text' => 'Focus keyword not found in content'];
        }
        
        if ($density > 3) {
            return ['level' => 'warning', 'text' => 'Keyword density too high - may appear as keyword stuffing'];
        }
        
        if ($density < 0.5) {
            return ['level' => 'warning', 'text' => 'Keyword density too low - use focus keyword more'];
        }
        
        if (!$in_title) {
            return ['level' => 'info', 'text' => 'Add focus keyword to page title for better SEO'];
        }
        
        return ['level' => 'success', 'text' => 'Focus keyword is well optimized'];
    }
    
    /**
     * Generate keyword optimization suggestions
     */
    private static function generateKeywordSuggestions($content, $focus_keyword, $keywords) {
        $suggestions = [];
        
        if (empty($focus_keyword)) {
            $suggestions[] = [
                'type' => 'error',
                'priority' => 'high',
                'suggestion' => 'Set a focus keyword for your page',
                'action' => 'Choose 1-2 main keywords you want to rank for'
            ];
        }
        
        // Suggest long-tail keywords
        if (count($keywords) > 5) {
            $top_5 = array_slice($keywords, 0, 5);
            $suggestions[] = [
                'type' => 'info',
                'priority' => 'low',
                'suggestion' => 'Consider targeting long-tail keyword variations',
                'action' => 'Top keywords: ' . implode(', ', array_map(function($k) { return $k['word']; }, $top_5)),
                'keywords' => $top_5
            ];
        }
        
        // Semantic related keywords
        $related = self::findRelatedKeywords($focus_keyword, $keywords);
        if (!empty($related)) {
            $suggestions[] = [
                'type' => 'info',
                'priority' => 'low',
                'suggestion' => 'Include semantic variations of your focus keyword',
                'action' => 'Try using: ' . implode(', ', array_slice($related, 0, 5)),
                'keywords' => $related
            ];
        }
        
        return $suggestions;
    }
    
    /**
     * Find related keywords
     */
    private static function findRelatedKeywords($focus_keyword, $keywords) {
        $related = [];
        
        if (empty($focus_keyword)) {
            return $related;
        }
        
        $keyword_parts = explode(' ', strtolower($focus_keyword));
        
        foreach ($keywords as $keyword) {
            $word = $keyword['word'];
            
            // Check for partial matches
            foreach ($keyword_parts as $part) {
                if (strlen($part) > 3 && stripos($word, $part) !== false && $word !== $part) {
                    $related[] = $word;
                    break;
                }
            }
        }
        
        return array_unique($related);
    }
    
    /**
     * Calculate overall keyword score
     */
    private static function calculateKeywordScore($focus_analysis, $keywords) {
        $score = 0;
        
        if (!empty($focus_analysis)) {
            $score = $focus_analysis['optimization_score'] ?? 0;
        }
        
        // Bonus for keyword variety
        if (count($keywords) > 20) {
            $score = min(100, $score + 10);
        }
        
        return $score;
    }
    
    /**
     * Get English stop words
     */
    private static function getStopWords() {
        return [
            'the', 'be', 'to', 'of', 'and', 'a', 'in', 'that', 'have', 'i',
            'it', 'for', 'not', 'on', 'with', 'he', 'as', 'you', 'do', 'at',
            'this', 'but', 'his', 'by', 'from', 'they', 'we', 'say', 'her', 'she',
            'or', 'an', 'will', 'my', 'one', 'all', 'would', 'there', 'their', 'what',
            'so', 'up', 'out', 'if', 'about', 'who', 'get', 'which', 'go', 'me',
            'when', 'make', 'can', 'like', 'time', 'no', 'just', 'him', 'know', 'take',
            'people', 'into', 'year', 'your', 'good', 'some', 'could', 'them', 'see', 'other',
            'than', 'then', 'now', 'look', 'only', 'come', 'its', 'over', 'think', 'also',
            'back', 'after', 'use', 'two', 'how', 'our', 'work', 'first', 'well', 'way',
            'even', 'new', 'want', 'because', 'any', 'these', 'give', 'day', 'most', 'us'
        ];
    }
    
    /**
     * Suggest improvements for weak keywords
     */
    public static function suggestKeywordImprovements($focus_keyword, $current_density) {
        $suggestions = [];
        
        if (empty($focus_keyword)) {
            return ['Choose a focus keyword'];
        }
        
        if ($current_density < 0.5) {
            $suggestions[] = "Increase keyword usage. Current density: {$current_density}%. Target: 0.5-2.5%";
        } elseif ($current_density > 3) {
            $suggestions[] = "Reduce keyword usage to avoid over-optimization. Current: {$current_density}%";
        }
        
        // Suggest variations
        $variations = self::generateKeywordVariations($focus_keyword);
        if (!empty($variations)) {
            $suggestions[] = "Use keyword variations: " . implode(', ', $variations);
        }
        
        return $suggestions;
    }
    
    /**
     * Generate keyword variations
     */
    private static function generateKeywordVariations($keyword) {
        $variations = [];
        $parts = explode(' ', $keyword);
        
        // Plural form
        $plural = $keyword . 's';
        $variations[] = $plural;
        
        // Reverse order if multiple words
        if (count($parts) > 1) {
            $variations[] = implode(' ', array_reverse($parts));
        }
        
        return array_unique($variations);
    }
}
?>
