"""Intent mapper for converting LLM intent to user preference vector."""

import numpy as np
import logging
from typing import Dict, Any, Optional, List

from learning.embedder import PatternEmbedder

logger = logging.getLogger(__name__)


class IntentMapper:
    """Mapper for converting intent JSON to user preference vector."""
    
    def __init__(self, embedder: PatternEmbedder):
        """Initialize intent mapper.
        
        Args:
            embedder: Pattern embedder instance
        """
        self.embedder = embedder
    
    def to_vector(self, intent_json: Dict[str, Any]) -> Optional[np.ndarray]:
        """Convert intent JSON to user preference vector.
        
        This method implements the feature selection and vector computation process:
        1. Extracts pattern_preference from intent JSON (feature selection)
        2. Encodes each pattern to embedding using Sentence Transformers
        3. Computes mean vector as initial user preference u_llm
        
        Args:
            intent_json: Intent dictionary from IntentEncoder
            
        Returns:
            User preference vector (mean of pattern embeddings), or None if conversion fails
        """
        try:
            # Step 1: Extract pattern_preference (feature selection)
            pattern_preference = intent_json.get("pattern_preference", [])
            
            if not pattern_preference:
                logger.warning("No pattern_preference in intent JSON")
                return None
            
            logger.info(f"IntentMapper: Extracted {len(pattern_preference)} patterns from intent")
            
            # Step 2: Filter out empty patterns
            valid_patterns = [p for p in pattern_preference if p and isinstance(p, list) and len(p) > 0]
            
            if not valid_patterns:
                logger.warning("No valid patterns in pattern_preference")
                return None
            
            logger.info(f"IntentMapper: {len(valid_patterns)} valid patterns after filtering")
            
            # Step 3: Encode patterns to vectors (feature extraction)
            # Each pattern like ["Park", "Restaurant"] is encoded to a vector
            vectors = []
            for i, pattern in enumerate(valid_patterns):
                try:
                    # pattern is a list of strings like ["Park", "Restaurant"]
                    logger.debug(f"IntentMapper: Encoding pattern {i+1}/{len(valid_patterns)}: {pattern}")
                    vec = self.embedder.encode_pattern(pattern)
                    if vec is not None:
                        vectors.append(vec)
                        logger.debug(f"IntentMapper: Pattern {pattern} encoded to vector (dim={len(vec)})")
                    else:
                        logger.warning(f"IntentMapper: Failed to encode pattern {pattern} - returned None")
                except Exception as e:
                    logger.warning(f"IntentMapper: Failed to encode pattern {pattern}: {e}")
                    continue
            
            if not vectors:
                logger.warning("IntentMapper: No valid vectors generated from patterns")
                return None
            
            logger.info(f"IntentMapper: Successfully encoded {len(vectors)} patterns to vectors")
            
            # Step 4: Compute mean vector as initial user preference u_llm
            # This represents the user's initial preference based on LLM-understood intent
            mean_vector = np.mean(vectors, axis=0)
            
            logger.info(f"IntentMapper: Generated user vector u_llm from {len(vectors)} patterns")
            logger.info(f"IntentMapper: Vector dimension: {mean_vector.shape}, norm: {np.linalg.norm(mean_vector):.4f}")
            
            return mean_vector
            
        except Exception as e:
            logger.error(f"IntentMapper: Error converting intent to vector: {e}", exc_info=True)
            return None

