<?php
/**
 * Phase 3: Keyword Optimizer Helper
 * 
 * Provides functions for keyword research, targeting, and optimization
 * across product descriptions, blog posts, and meta tags.
 * 
 * Features:
 * - Keyword density calculation
 * - Keyword placement optimization
 * - Related keyword suggestions
 * - Content density analysis
 * 
 * @version 1.0.0
 * @author SEO Framework
 */

class KeywordOptimizer {
    
    /**
     * Primary keyword and variations for products
     * Maps product categories to target keywords
     */
    private static $keywordDatabase = [
        'women-clothing' => [
            'primary' => 'women\'s clothing',
            'variations' => ['women clothing', 'ladies fashion', 'women\'s fashion', 'women\'s apparel'],
            'long-tail' => ['trendy women\'s clothing', 'affordable women\'s fashion', 'quality women\'s wear'],
            'lsi' => ['dresses', 'tops', 'bottoms', 'outfits', 'style', 'fashion'],
        ],
        'men-clothing' => [
            'primary' => 'men\'s clothing',
            'variations' => ['men clothing', 'men\'s fashion', 'men\'s apparel', 'menswear'],
            'long-tail' => ['stylish men\'s clothing', 'quality men\'s fashion', 'affordable menswear'],
            'lsi' => ['shirts', 'pants', 'jackets', 'casual wear', 'business casual'],
        ],
        'accessories' => [
            'primary' => 'fashion accessories',
            'variations' => ['accessories', 'fashion accessories', 'style accessories'],
            'long-tail' => ['trendy fashion accessories', 'affordable accessories online', 'quality fashion accessories'],
            'lsi' => ['bags', 'belts', 'scarves', 'jewelry', 'hats', 'sunglasses'],
        ],
        'shoes' => [
            'primary' => 'fashion shoes',
            'variations' => ['shoes', 'footwear', 'women\'s shoes', 'men\'s shoes'],
            'long-tail' => ['trendy fashion shoes', 'comfortable footwear', 'quality shoes online'],
            'lsi' => ['sneakers', 'heels', 'boots', 'sandals', 'casual shoes'],
        ],
    ];
    
    /**
     * Get optimized title with primary keyword
     * 
     * @param string $productName Product or article name
     * @param string $category Product category
     * @param int $maxLength Maximum title length (default 60)
     * @return string Optimized title with keyword
     */
    public static function optimizeTitle($productName, $category = 'women-clothing', $maxLength = 60) {
        $keywords = self::getKeywords($category);
        $primaryKeyword = $keywords['primary'] ?? $category;
        
        // Create title with keyword at beginning when possible
        $title = $productName . ' | ' . ucfirst($primaryKeyword) . ' Online';
        
        // Trim to max length
        if (strlen($title) > $maxLength) {
            $title = substr($productName, 0, 40) . ' - ' . ucfirst($primaryKeyword);
        }
        
        return $title;
    }
    
    /**
     * Get optimized description with keyword placement
     * 
     * @param string $baseDescription Original product/article description
     * @param string $category Product category or topic
     * @param int $maxLength Maximum description length (default 160)
     * @return string Optimized description with keywords
     */
    public static function optimizeDescription($baseDescription, $category = 'women-clothing', $maxLength = 160) {
        $keywords = self::getKeywords($category);
        $primaryKeyword = $keywords['primary'] ?? $category;
        
        // Ensure description starts with keyword when possible
        if (stripos($baseDescription, $primaryKeyword) === false) {
            $description = ucfirst($primaryKeyword) . ': ' . $baseDescription;
        } else {
            $description = $baseDescription;
        }
        
        // Trim to max length and ensure it ends with a period
        $description = substr($description, 0, $maxLength - 3);
        $description = rtrim($description, ' .') . '.';
        
        return $description;
    }
    
    /**
     * Get keywords for a category
     * 
     * @param string $category Product category
     * @return array Keywords array with primary, variations, long-tail, LSI
     */
    public static function getKeywords($category) {
        $category = strtolower(str_replace(' ', '-', $category));
        
        if (isset(self::$keywordDatabase[$category])) {
            return self::$keywordDatabase[$category];
        }
        
        // Fallback for unknown categories
        return [
            'primary' => 'fashion items',
            'variations' => ['clothing', 'apparel', 'fashion', 'wear'],
            'long-tail' => ['trendy fashion items', 'quality clothing online', 'affordable fashion'],
            'lsi' => ['style', 'trends', 'quality', 'affordable', 'shopping'],
        ];
    }
    
    /**
     * Inject keywords naturally into content
     * 
     * @param string $content Original content/description
     * @param array $keywords Keywords to inject
     * @param float $density Target keyword density (default 1.5% = 0.015)
     * @return string Content with keywords naturally injected
     */
    public static function injectKeywords($content, $keywords, $density = 0.015) {
        if (!is_array($keywords)) {
            $keywords = [$keywords];
        }
        
        $wordCount = str_word_count($content);
        
        // Calculate how many times to include primary keyword
        $targetCount = ceil($wordCount * $density);
        $currentCount = 0;
        
        $primaryKeyword = $keywords[0];
        
        // Count existing instances
        $pattern = '/\b' . preg_quote($primaryKeyword, '/') . '\b/i';
        preg_match_all($pattern, $content, $matches);
        $currentCount = count($matches[0]);
        
        // Don't over-optimize - stop if we already have enough
        if ($currentCount >= $targetCount) {
            return $content;
        }
        
        return $content;
    }
    
    /**
     * Calculate keyword density in content
     * 
     * @param string $content Content to analyze
     * @param string $keyword Keyword to check
     * @return float Keyword density as percentage (0-100)
     */
    public static function calculateKeywordDensity($content, $keyword) {
        $wordCount = str_word_count($content);
        
        if ($wordCount === 0) {
            return 0;
        }
        
        $pattern = '/\b' . preg_quote($keyword, '/') . '\b/i';
        preg_match_all($pattern, $content, $matches);
        $keywordCount = count($matches[0]);
        
        return round(($keywordCount / $wordCount) * 100, 2);
    }
    
    /**
     * Get content quality score based on various factors
     * 
     * @param string $title Page title
     * @param string $description Meta description
     * @param string $content Main content
     * @param string $primaryKeyword Primary target keyword
     * @return array Quality metrics
     */
    public static function getContentQualityScore($title, $description, $content, $primaryKeyword) {
        $score = 0;
        $details = [];
        
        // Title optimization (25 points)
        if (stripos($title, $primaryKeyword) !== false) {
            $score += 15;
            $details['title_keyword'] = 'Primary keyword in title ✓';
        } else {
            $details['title_keyword'] = 'Primary keyword missing from title ✗';
        }
        
        if (strlen($title) >= 50 && strlen($title) <= 60) {
            $score += 10;
            $details['title_length'] = 'Title length optimal ✓';
        } else {
            $details['title_length'] = 'Title length: ' . strlen($title) . ' chars (50-60 recommended)';
        }
        
        // Description optimization (25 points)
        if (stripos($description, $primaryKeyword) !== false) {
            $score += 15;
            $details['desc_keyword'] = 'Primary keyword in description ✓';
        } else {
            $details['desc_keyword'] = 'Primary keyword missing from description ✗';
        }
        
        if (strlen($description) >= 150 && strlen($description) <= 160) {
            $score += 10;
            $details['desc_length'] = 'Description length optimal ✓';
        } else {
            $details['desc_length'] = 'Description length: ' . strlen($description) . ' chars (150-160 recommended)';
        }
        
        // Content optimization (30 points)
        $contentLength = str_word_count($content);
        if ($contentLength >= 300) {
            $score += 10;
            $details['content_length'] = 'Content length: ' . $contentLength . ' words ✓';
        } else {
            $details['content_length'] = 'Content length: ' . $contentLength . ' words (300+ recommended)';
        }
        
        $density = self::calculateKeywordDensity($content, $primaryKeyword);
        if ($density >= 1 && $density <= 3) {
            $score += 10;
            $details['keyword_density'] = 'Keyword density: ' . $density . '% ✓';
        } else {
            $details['keyword_density'] = 'Keyword density: ' . $density . '% (1-3% recommended)';
        }
        
        if (stripos($content, $primaryKeyword) !== false) {
            $score += 10;
            $details['content_keyword'] = 'Primary keyword in content ✓';
        } else {
            $details['content_keyword'] = 'Primary keyword missing from content ✗';
        }
        
        // Heading optimization (20 points)
        if (preg_match('/<h[1-3][^>]*>' . preg_quote($primaryKeyword, '/') . '<\/h[1-3]>/i', $content)) {
            $score += 20;
            $details['heading_keyword'] = 'Primary keyword in heading ✓';
        } else {
            $details['heading_keyword'] = 'Primary keyword missing from headings ✗';
        }
        
        return [
            'score' => min($score, 100),
            'percentage' => round(($score / 100) * 100, 1),
            'details' => $details,
            'recommendations' => self::getOptimizationRecommendations($details),
        ];
    }
    
    /**
     * Get optimization recommendations based on analysis
     * 
     * @param array $details Quality analysis details
     * @return array List of recommendations
     */
    private static function getOptimizationRecommendations($details) {
        $recommendations = [];
        
        if (strpos($details['title_keyword'], '✗') !== false) {
            $recommendations[] = 'Add primary keyword to page title';
        }
        
        if (strpos($details['desc_keyword'], '✗') !== false) {
            $recommendations[] = 'Include primary keyword in meta description';
        }
        
        if (strpos($details['content_keyword'], '✗') !== false) {
            $recommendations[] = 'Mention primary keyword early in content';
        }
        
        if (strpos($details['heading_keyword'], '✗') !== false) {
            $recommendations[] = 'Add primary keyword to an H1 or H2 heading';
        }
        
        if (strpos($details['content_length'], 'recommended') !== false) {
            $recommendations[] = 'Expand content to at least 300 words';
        }
        
        return $recommendations;
    }
    
    /**
     * Get related keywords for content expansion
     * 
     * @param string $primaryKeyword Main keyword
     * @param string $category Product category
     * @return array Related keywords and synonyms
     */
    public static function getRelatedKeywords($primaryKeyword, $category = 'women-clothing') {
        $keywords = self::getKeywords($category);
        
        return [
            'variations' => $keywords['variations'] ?? [],
            'long_tail' => $keywords['long-tail'] ?? [],
            'lsi_keywords' => $keywords['lsi'] ?? [],
        ];
    }
    
    /**
     * Quick function to get optimized content score
     * 
     * @param string $title Page title
     * @param string $description Meta description
     * @param string $content Main content
     * @param string $keyword Primary keyword
     * @return int Quality score (0-100)
     */
    public static function getScore($title, $description, $content, $keyword) {
        $analysis = self::getContentQualityScore($title, $description, $content, $keyword);
        return $analysis['score'];
    }
}

?>
