import re
from typing import Dict, List, Tuple, Any
from dataclasses import dataclass
import numpy as np

@dataclass
class MatchResult:
    rule_category: str
    rule_type: str
    confidence: float
    matched_phrases: List[str]
    reasoning: str

class SimpleNLPMatcher:
    """Simplified NLP matcher that doesn't require heavy ML libraries"""

    def __init__(self):
        print("🔄 Initializing Simple NLP matcher...")

        # Key phrase patterns for matching
        print("   Loading pattern matching rules...")
        self.positive_patterns = {
            'music_first': [
                r'\bmusic[- ]first\b', r'\bmusic company\b', r'\bartist empowerment\b',
                r'\bcreativity\b', r'\bimagination\b', r'\bmusic[- ]making\b',
                r'\bmusic creation\b', r'\bmusical\b', r'\bcreative\b'
            ],
            'inclusive_tone': [
                r'\binclusive\b', r'\baccessible\b', r'\bcommunity\b', r'\bconnection\b',
                r'\bbelonging\b', r'\bwelcoming\b', r'\btogether\b', r'\bjoin\b'
            ],
            'human_centered': [
                r'\bhuman\b', r'\bself[- ]expression\b', r'\bmeaningful creativity\b',
                r'\bartist\b(?!\s+replacement)', r'\bcollaborat\w+\b', r'\bempower\w*\b',
                r'\bpeople\b', r'\bmusician\b', r'\bcreator\b'
            ],
            'authentic_voice': [
                r'\bauthentic\b', r'\bgenuine\b', r'\bpoetic\b', r'\blyrical\b',
                r'\bplayful\b', r'\bexperimental\b', r'\boriginal\b', r'\bunique\b'
            ],
            'positive_messaging': [
                r'\binspir\w+\b', r'\bmagic\b', r'\bjoy\b', r'\bfun\b', r'\bexplore\b',
                r'\bdiscover\b', r'\bpassion\b', r'\bcraft\b', r'\bartistry\b'
            ]
        }

        self.negative_patterns = {
            'ai_first': [
                r'\bAI[- ]first\b', r'\bAI music company\b', r'\btechnology over\b',
                r'\btech[- ]heavy\b', r'\bAI does everything\b', r'\bAI[- ]powered\b',
                r'\balgorithm\w*\b', r'\bmachine learning\b', r'\bartificial intelligence\b'
            ],
            'replacement_language': [
                r'\breplace\w* (?:human )?artist\w*\b', r'\bmusic is broken\b',
                r'\bmake music great again\b', r'\bdemocratize music\b',
                r'\btake over\b', r'\beliminate\b.*\bneed\b', r'\bno more\b.*\bmusician\b'
            ],
            'tech_bro': [
                r'\bdisrupt\w*\b', r'\bscale\b', r'\bleverage\b', r'\bsynerg\w+\b',
                r'\boptimize\b', r'\bmonetize\b', r'\bgrowth hack\b', r'\bunicorn\b',
                r'\bpivot\b', r'\biterations?\b'
            ],
            'trivializing': [
                r'\beasy\b.*\bmusic\b', r'\beffortless\b.*\bcreation\b',
                r'\bcheap\b.*\bslop\b', r'\bshortcut\b', r'\binstant\b.*\bhit\b',
                r'\bautomatic\b.*\bsuccess\b', r'\bno skill\b.*\brequired\b'
            ],
            'salesy_tone': [
                r'\bREVOLUTIONARY[!]+\b', r'\bGAME[- ]CHANGER[!]*\b',
                r'\bUNLIMITED[!]+\b', r'\bFREE FOREVER[!]+\b', r'\bBEST EVER[!]+\b',
                r'\bINCREDIBLE[!]+\b', r'\bMIND[- ]BLOWING[!]+\b', r'\bUNBELIEVABLE[!]+\b'
            ]
        }

        # Weighted keywords for semantic-like matching
        self.approval_keywords = {
            'music': 3.0, 'artist': 2.5, 'creative': 2.0, 'community': 2.0,
            'imagination': 2.0, 'authentic': 1.8, 'empowerment': 2.5,
            'collaboration': 2.0, 'expression': 1.8, 'inspiration': 1.5,
            'craft': 1.8, 'artistry': 2.0, 'human': 1.5, 'people': 1.2,
            'musician': 2.0, 'creator': 1.8
        }

        self.rejection_keywords = {
            'ai': 2.0, 'algorithm': 2.5, 'automate': 2.0, 'replace': 3.0,
            'disrupt': 2.5, 'leverage': 1.8, 'optimize': 1.8, 'scale': 1.5,
            'democratize': 2.0, 'revolutionize': 2.0, 'effortless': 2.0,
            'instant': 1.8, 'automatic': 1.8
        }

        print("   ✅ Simple NLP matcher ready!")

    def analyze_content(self, content: str, approval_rules: List, rejection_rules: List) -> Dict[str, Any]:
        print(f"🔍 Analyzing content: '{content[:50]}{'...' if len(content) > 50 else ''}'")
        content_lower = content.lower()

        # Pattern matching
        print("   Checking pattern matches...")
        pattern_matches = self._match_patterns(content_lower)
        print(f"   Found {len(pattern_matches)} pattern matches")

        # Keyword scoring
        print("   Performing keyword analysis...")
        keyword_matches = self._keyword_scoring(content_lower)
        print(f"   Found {len(keyword_matches)} keyword matches")

        # Combine results
        all_matches = pattern_matches + keyword_matches
        print(f"   Total matches: {len(all_matches)}")

        # Calculate overall score
        approval_score = sum(m.confidence for m in all_matches if m.rule_type == 'approve')
        rejection_score = sum(m.confidence for m in all_matches if m.rule_type == 'reject')

        net_score = approval_score - rejection_score
        approved = net_score > 0 and rejection_score < 0.7

        print(f"   📊 Scores - Approval: {approval_score:.2f}, Rejection: {rejection_score:.2f}, Net: {net_score:.2f}")
        print(f"   🎯 Decision: {'APPROVED' if approved else 'REJECTED'}")

        # Generate reasoning
        reasoning = self._generate_reasoning(all_matches, approved, net_score)

        return {
            "approved": approved,
            "approval_score": approval_score,
            "rejection_score": rejection_score,
            "net_score": net_score,
            "matches": all_matches,
            "reasoning": reasoning
        }

    def _match_patterns(self, content: str) -> List[MatchResult]:
        matches = []

        # Check positive patterns
        for category, patterns in self.positive_patterns.items():
            for pattern in patterns:
                if re.search(pattern, content, re.IGNORECASE):
                    matches.append(MatchResult(
                        rule_category=category,
                        rule_type='approve',
                        confidence=0.8,
                        matched_phrases=[pattern],
                        reasoning=f"Contains positive pattern: {pattern}"
                    ))

        # Check negative patterns
        for category, patterns in self.negative_patterns.items():
            for pattern in patterns:
                if re.search(pattern, content, re.IGNORECASE):
                    matches.append(MatchResult(
                        rule_category=category,
                        rule_type='reject',
                        confidence=0.9,
                        matched_phrases=[pattern],
                        reasoning=f"Contains problematic pattern: {pattern}"
                    ))

        return matches

    def _keyword_scoring(self, content: str) -> List[MatchResult]:
        matches = []
        words = re.findall(r'\b\w+\b', content.lower())

        # Check approval keywords
        approval_score = 0
        found_approval_words = []
        for word in words:
            if word in self.approval_keywords:
                weight = self.approval_keywords[word]
                approval_score += weight
                found_approval_words.append(f"{word}({weight})")

        if approval_score > 0:
            confidence = min(approval_score / 10.0, 0.9)  # Normalize to 0-0.9
            matches.append(MatchResult(
                rule_category="keyword_approval",
                rule_type='approve',
                confidence=confidence,
                matched_phrases=found_approval_words[:3],  # Top 3
                reasoning=f"Contains positive keywords (score: {approval_score:.1f})"
            ))

        # Check rejection keywords
        rejection_score = 0
        found_rejection_words = []
        for word in words:
            if word in self.rejection_keywords:
                weight = self.rejection_keywords[word]
                rejection_score += weight
                found_rejection_words.append(f"{word}({weight})")

        if rejection_score > 0:
            confidence = min(rejection_score / 8.0, 0.95)  # Normalize to 0-0.95
            matches.append(MatchResult(
                rule_category="keyword_rejection",
                rule_type='reject',
                confidence=confidence,
                matched_phrases=found_rejection_words[:3],  # Top 3
                reasoning=f"Contains problematic keywords (score: {rejection_score:.1f})"
            ))

        return matches

    def _generate_reasoning(self, matches: List[MatchResult], approved: bool, net_score: float) -> str:
        if not matches:
            return "No significant matches found against brand guidelines."

        approve_matches = [m for m in matches if m.rule_type == 'approve']
        reject_matches = [m for m in matches if m.rule_type == 'reject']

        reasoning_parts = []

        if approved:
            reasoning_parts.append("✅ APPROVED:")
            if approve_matches:
                top_approve = max(approve_matches, key=lambda x: x.confidence)
                reasoning_parts.append(f"Strong alignment with {top_approve.rule_category}")
            if reject_matches:
                reasoning_parts.append(f"Minor concerns noted but overall positive (score: {net_score:.2f})")
        else:
            reasoning_parts.append("❌ REJECTED:")
            if reject_matches:
                top_reject = max(reject_matches, key=lambda x: x.confidence)
                reasoning_parts.append(f"Violates {top_reject.rule_category} guidelines")
            if approve_matches:
                reasoning_parts.append("Some positive elements found but insufficient to approve")

        # Add specific match details (limit to top 2)
        top_matches = sorted(matches, key=lambda x: x.confidence, reverse=True)[:2]
        for match in top_matches:
            reasoning_parts.append(f"• {match.reasoning}")

        return " ".join(reasoning_parts)