<?php

namespace App\Services;

class ProfanityFilterService
{
    /**
     * List of profanity words to filter
     * In a real implementation, this would be loaded from a database or config file
     *
     * @var array
     */
    protected $profanityWords = [
        'damn', 'hell', 'crap', 'piss', 'ass', 'arse', 'asshole', 'bastard',
        'bitch', 'bollocks', 'bugger', 'bullshit', 'cock', 'cunt', 'dick',
        'dickhead', 'fag', 'faggot', 'fuck', 'fucker', 'fucking', 'goddamn',
        'idiot', 'jackass', 'jerk', 'moron', 'motherfucker', 'nigga', 'nigger',
        'pissed', 'prick', 'pussy', 'shit', 'shitty', 'slut', 'twat', 'wanker',
        'whore'
    ];
    
    /**
     * List of brand-specific words to filter
     * This would be customized per brand
     *
     * @var array
     */
    protected $brandSpecificWords = [];
    
    /**
     * Set brand-specific words to filter
     *
     * @param array $words
     * @return self
     */
    public function setBrandSpecificWords(array $words)
    {
        $this->brandSpecificWords = array_map('strtolower', $words);
        return $this;
    }
    
    /**
     * Check if text contains profanity
     *
     * @param string $text
     * @return bool
     */
    public function hasProfanity($text)
    {
        $text = strtolower($text);
        
        // Check for profanity words
        foreach ($this->profanityWords as $word) {
            if ($this->containsWord($text, $word)) {
                return true;
            }
        }
        
        // Check for brand-specific words
        foreach ($this->brandSpecificWords as $word) {
            if ($this->containsWord($text, $word)) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * Filter profanity from text
     *
     * @param string $text
     * @param string $replacement
     * @return string
     */
    public function filter($text, $replacement = '***')
    {
        $text = strtolower($text);
        
        // Filter profanity words
        foreach ($this->profanityWords as $word) {
            $text = $this->replaceWord($text, $word, $replacement);
        }
        
        // Filter brand-specific words
        foreach ($this->brandSpecificWords as $word) {
            $text = $this->replaceWord($text, $word, $replacement);
        }
        
        return $text;
    }
    
    /**
     * Get profanity score (0-100) based on severity and frequency
     *
     * @param string $text
     * @return int
     */
    public function getProfanityScore($text)
    {
        $text = strtolower($text);
        $score = 0;
        $wordCount = str_word_count($text);
        
        if ($wordCount == 0) {
            return 0;
        }
        
        // Check for profanity words and calculate score
        foreach ($this->profanityWords as $word) {
            if ($this->containsWord($text, $word)) {
                // Severity rating (1-10) - higher for more offensive words
                $severity = $this->getSeverityRating($word);
                $score += $severity * 5; // Base score multiplier
            }
        }
        
        // Check for brand-specific words
        foreach ($this->brandSpecificWords as $word) {
            if ($this->containsWord($text, $word)) {
                $score += 10; // Fixed score for brand-specific words
            }
        }
        
        // Normalize score to 0-100
        $score = min(100, $score);
        
        return $score;
    }
    
    /**
     * Check if text contains a specific word (whole word match)
     *
     * @param string $text
     * @param string $word
     * @return bool
     */
    protected function containsWord($text, $word)
    {
        // Use word boundaries to match whole words only
        return preg_match('/\b' . preg_quote($word, '/') . '\b/i', $text) === 1;
    }
    
    /**
     * Replace a word with a replacement string
     *
     * @param string $text
     * @param string $word
     * @param string $replacement
     * @return string
     */
    protected function replaceWord($text, $word, $replacement)
    {
        // Use word boundaries to replace whole words only
        return preg_replace('/\b' . preg_quote($word, '/') . '\b/i', $replacement, $text);
    }
    
    /**
     * Get severity rating for a profanity word (1-10)
     *
     * @param string $word
     * @return int
     */
    protected function getSeverityRating($word)
    {
        $severityRatings = [
            // Low severity (1-3)
            'crap' => 1, 'hell' => 2, 'damn' => 2, 'piss' => 2,
            
            // Medium severity (4-6)
            'ass' => 4, 'arse' => 4, 'idiot' => 4, 'jerk' => 4,
            'moron' => 5, 'jackass' => 5, 'prick' => 5, 'twat' => 5,
            
            // High severity (7-10)
            'asshole' => 7, 'bastard' => 7, 'bitch' => 7, 'bollocks' => 7,
            'bugger' => 7, 'bullshit' => 7, 'cock' => 7, 'cunt' => 8,
            'dick' => 7, 'dickhead' => 8, 'fag' => 9, 'faggot' => 10,
            'fuck' => 8, 'fucker' => 9, 'fucking' => 8, 'goddamn' => 7,
            'motherfucker' => 10, 'nigga' => 10, 'nigger' => 10, 'pissed' => 6,
            'pussy' => 8, 'shit' => 6, 'shitty' => 6, 'slut' => 9,
            'wanker' => 7, 'whore' => 9
        ];
        
        return $severityRatings[$word] ?? 5;
    }
}