"""
Claude Haiku Content Analyzer

Uses Claude Haiku for cost-effective content classification, topic extraction,
sentiment analysis, and HVAC-specific categorization.
"""

import os
import json
import logging
from typing import Dict, List, Any, Optional
from dataclasses import dataclass
import anthropic
from tenacity import retry, stop_after_attempt, wait_exponential


@dataclass
class ContentAnalysisResult:
    """Result of content analysis"""
    content_id: str
    topics: List[str]
    products: List[str] 
    difficulty: str
    content_type: str
    sentiment: float
    keywords: List[str]
    hvac_relevance: float
    engagement_prediction: float


class ClaudeHaikuAnalyzer:
    """Claude Haiku-based content analyzer for HVAC content"""
    
    def __init__(self, api_key: Optional[str] = None):
        """Initialize Claude Haiku analyzer"""
        self.api_key = api_key or os.getenv('ANTHROPIC_API_KEY')
        if not self.api_key:
            raise ValueError("ANTHROPIC_API_KEY environment variable or api_key parameter required")
            
        self.client = anthropic.Anthropic(api_key=self.api_key)
        self.logger = logging.getLogger(__name__)
        
        # HVAC classification categories
        self.topics = [
            'heat_pumps', 'air_conditioning', 'refrigeration', 'electrical', 
            'installation', 'troubleshooting', 'tools', 'business', 'safety', 
            'codes', 'maintenance', 'smart_hvac', 'refrigerants', 'ductwork',
            'ventilation', 'controls', 'energy_efficiency', 'commercial',
            'residential', 'training'
        ]
        
        self.products = [
            'thermostats', 'compressors', 'condensers', 'evaporators', 'ductwork',
            'meters', 'gauges', 'recovery_equipment', 'refrigerants', 'safety_equipment',
            'manifolds', 'vacuum_pumps', 'brazing_equipment', 'leak_detectors',
            'micron_gauges', 'digital_manifolds', 'superheat_subcooling_calculators'
        ]
        
        self.content_types = [
            'tutorial', 'troubleshooting', 'product_review', 'industry_news',
            'business_advice', 'safety_tips', 'code_explanation', 'installation_guide',
            'maintenance_procedure', 'tool_demonstration'
        ]
        
        self.difficulties = ['beginner', 'intermediate', 'advanced']

    @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10))
    def analyze_content(self, content_item: Dict[str, Any]) -> ContentAnalysisResult:
        """Analyze a single content item"""
        
        # Extract text content for analysis
        text_content = self._extract_text_content(content_item)
        
        if not text_content:
            return self._create_fallback_result(content_item)
            
        try:
            analysis = self._call_claude_haiku(text_content, content_item)
            return self._parse_analysis_result(content_item, analysis)
            
        except Exception as e:
            self.logger.error(f"Error analyzing content {content_item.get('id', 'unknown')}: {e}")
            return self._create_fallback_result(content_item)

    def analyze_content_batch(self, content_items: List[Dict[str, Any]], batch_size: int = 5) -> List[ContentAnalysisResult]:
        """Analyze content items in batches for cost efficiency"""
        results = []
        
        for i in range(0, len(content_items), batch_size):
            batch = content_items[i:i + batch_size]
            
            try:
                batch_results = self._analyze_batch(batch)
                results.extend(batch_results)
                
            except Exception as e:
                self.logger.error(f"Error analyzing batch {i//batch_size + 1}: {e}")
                # Fallback to individual analysis for this batch
                for item in batch:
                    try:
                        result = self.analyze_content(item)
                        results.append(result)
                    except Exception as item_error:
                        self.logger.error(f"Error in individual fallback for {item.get('id')}: {item_error}")
                        results.append(self._create_fallback_result(item))
                        
        return results

    def _analyze_batch(self, batch: List[Dict[str, Any]]) -> List[ContentAnalysisResult]:
        """Analyze a batch of content items together"""
        
        batch_prompt = self._create_batch_prompt(batch)
        
        message = self.client.messages.create(
            model="claude-3-haiku-20240307",
            max_tokens=4000,
            temperature=0.1,
            messages=[{"role": "user", "content": batch_prompt}]
        )
        
        response_text = message.content[0].text
        
        try:
            batch_analysis = json.loads(response_text)
            results = []
            
            for i, item in enumerate(batch):
                if i < len(batch_analysis.get('analyses', [])):
                    analysis = batch_analysis['analyses'][i]
                    result = self._parse_analysis_result(item, analysis)
                    results.append(result)
                else:
                    results.append(self._create_fallback_result(item))
                    
            return results
            
        except (json.JSONDecodeError, KeyError) as e:
            self.logger.error(f"Error parsing batch analysis response: {e}")
            raise

    def _create_batch_prompt(self, batch: List[Dict[str, Any]]) -> str:
        """Create prompt for batch analysis"""
        
        content_summaries = []
        for i, item in enumerate(batch):
            text_content = self._extract_text_content(item)
            content_summaries.append({
                'index': i,
                'id': item.get('id', f'item_{i}'),
                'title': item.get('title', 'No title')[:100],
                'description': item.get('description', 'No description')[:300],
                'content_preview': text_content[:500] if text_content else 'No content'
            })

        return f"""
Analyze these HVAC/R content pieces and classify each one. Return JSON only.

Available categories:
- Topics: {', '.join(self.topics)}
- Products: {', '.join(self.products)}  
- Content Types: {', '.join(self.content_types)}
- Difficulties: {', '.join(self.difficulties)}

For each content item, determine:
1. Primary topics (1-3 most relevant)
2. Products mentioned (0-5 most relevant)
3. Difficulty level (beginner/intermediate/advanced)
4. Content type (single most appropriate)
5. Sentiment (-1.0 to 1.0, where -1=very negative, 0=neutral, 1=very positive)
6. Key HVAC keywords (3-8 technical terms)
7. HVAC relevance (0.0 to 1.0, how relevant to HVAC professionals)
8. Engagement prediction (0.0 to 1.0, how likely to engage HVAC audience)

Content to analyze:
{json.dumps(content_summaries, indent=2)}

Return format:
{{
  "analyses": [
    {{
      "index": 0,
      "topics": ["topic1", "topic2"],
      "products": ["product1"],
      "difficulty": "intermediate", 
      "content_type": "tutorial",
      "sentiment": 0.7,
      "keywords": ["keyword1", "keyword2", "keyword3"],
      "hvac_relevance": 0.9,
      "engagement_prediction": 0.8
    }}
  ]
}}
"""

    def _call_claude_haiku(self, text_content: str, content_item: Dict[str, Any]) -> Dict[str, Any]:
        """Make API call to Claude Haiku for single item analysis"""
        
        prompt = f"""
Analyze this HVAC/R content and classify it. Return JSON only.

Available categories:
- Topics: {', '.join(self.topics)}
- Products: {', '.join(self.products)}
- Content Types: {', '.join(self.content_types)}
- Difficulties: {', '.join(self.difficulties)}

Content to analyze:
Title: {content_item.get('title', 'No title')}
Description: {content_item.get('description', 'No description')}
Content: {text_content[:1000]}

Determine:
1. Primary topics (1-3 most relevant)
2. Products mentioned (0-5 most relevant)  
3. Difficulty level
4. Content type
5. Sentiment (-1.0 to 1.0)
6. Key HVAC keywords (3-8 technical terms)
7. HVAC relevance (0.0 to 1.0)
8. Engagement prediction (0.0 to 1.0)

Return format:
{{
  "topics": ["topic1", "topic2"],
  "products": ["product1"],
  "difficulty": "intermediate",
  "content_type": "tutorial", 
  "sentiment": 0.7,
  "keywords": ["keyword1", "keyword2"],
  "hvac_relevance": 0.9,
  "engagement_prediction": 0.8
}}
"""

        message = self.client.messages.create(
            model="claude-3-haiku-20240307",
            max_tokens=1000,
            temperature=0.1,
            messages=[{"role": "user", "content": prompt}]
        )
        
        response_text = message.content[0].text
        return json.loads(response_text)

    def _extract_text_content(self, content_item: Dict[str, Any]) -> str:
        """Extract text content from various content item formats"""
        
        text_parts = []
        
        # Add title
        if title := content_item.get('title'):
            text_parts.append(title)
            
        # Add description
        if description := content_item.get('description'):
            text_parts.append(description)
            
        # Add transcript if available (YouTube)
        if transcript := content_item.get('transcript'):
            text_parts.append(transcript[:2000])  # Limit transcript length
            
        # Add content if available (blog posts)
        if content := content_item.get('content'):
            text_parts.append(content[:2000])  # Limit content length
            
        # Add hashtags (Instagram)
        if hashtags := content_item.get('hashtags'):
            if isinstance(hashtags, str):
                text_parts.append(hashtags)
            elif isinstance(hashtags, list):
                text_parts.append(' '.join(hashtags))
        
        return ' '.join(text_parts)

    def _parse_analysis_result(self, content_item: Dict[str, Any], analysis: Dict[str, Any]) -> ContentAnalysisResult:
        """Parse Claude's analysis response into ContentAnalysisResult"""
        
        return ContentAnalysisResult(
            content_id=content_item.get('id', 'unknown'),
            topics=analysis.get('topics', []),
            products=analysis.get('products', []),
            difficulty=analysis.get('difficulty', 'intermediate'),
            content_type=analysis.get('content_type', 'tutorial'),
            sentiment=float(analysis.get('sentiment', 0.0)),
            keywords=analysis.get('keywords', []),
            hvac_relevance=float(analysis.get('hvac_relevance', 0.5)),
            engagement_prediction=float(analysis.get('engagement_prediction', 0.5))
        )

    def _create_fallback_result(self, content_item: Dict[str, Any]) -> ContentAnalysisResult:
        """Create a fallback result when analysis fails"""
        
        return ContentAnalysisResult(
            content_id=content_item.get('id', 'unknown'),
            topics=['maintenance'],  # Default fallback topic
            products=[],
            difficulty='intermediate',
            content_type='tutorial',
            sentiment=0.0,
            keywords=[],
            hvac_relevance=0.5,
            engagement_prediction=0.5
        )