import os
import base64
import json
import logging
from typing import Dict, List, Tuple, Optional
import openai
from PIL import Image
import io
from dotenv import load_dotenv
from content_moderator import ContentModerator

# Load environment variables
load_dotenv()

# Set up logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('viral_velocity.log'),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

class ViralVelocityScorer:
    """
    Viral Velocity Image Scorer using OpenAI GPT-4 Vision
    Implements the 4-pillar scoring system for social media images with personalization
    """
    
    def __init__(self):
        """Initialize the scorer with OpenAI"""
        logger.info("Initializing ViralVelocityScorer...")
        
        api_key = os.getenv('OPENAI_API_KEY')
        if not api_key:
            logger.error("OPENAI_API_KEY not found in environment variables")
            raise ValueError("OPENAI_API_KEY not found in environment variables")
        
        logger.info("OpenAI API key found, initializing client...")
        # Initialize OpenAI client with explicit configuration
        try:
            self.client = openai.OpenAI(api_key=api_key)
            logger.info("OpenAI client initialized successfully")
        except Exception as e:
            logger.error(f"Failed to initialize OpenAI client: {e}")
            # Try alternative initialization method
            try:
                openai.api_key = api_key
                self.client = openai.OpenAI()
                logger.info("OpenAI client initialized with alternative method")
            except Exception as e2:
                logger.error(f"Alternative initialization also failed: {e2}")
                raise ValueError(f"Could not initialize OpenAI client: {e2}")
        
        # Scoring weights as per project specification
        self.weights = {
            'technical_quality': 0.25,
            'compositional_strength': 0.25,
            'psychological_engagement': 0.30,
            'trend_zeitgeist': 0.20
        }
        logger.info(f"Scoring weights initialized: {self.weights}")
        
        # Initialize content moderator
        logger.info("Initializing content moderator...")
        self.content_moderator = ContentModerator()
        logger.info("ViralVelocityScorer initialization complete")
    
    def analyze_image(self, image_path: str, user_preferences: Optional[Dict] = None) -> Dict:
        """
        Analyze an image and return comprehensive scoring (legacy method)
        """
        logger.info(f"Starting legacy image analysis for: {image_path}")
        return self.analyze_image_efficient(image_path, user_preferences)
    
    def analyze_image_efficient(self, image_path: str, user_preferences: Optional[Dict] = None) -> Dict:
        """
        Analyze an image more efficiently by combining multiple analyses into fewer API calls
        Now supports user preferences for personalized scoring
        """
        logger.info(f"Starting efficient image analysis for: {image_path}")
        if user_preferences:
            logger.info(f"User preferences: {user_preferences}")
        else:
            logger.info("No user preferences provided, using generic scoring")
        
        try:
            # Load and prepare image
            logger.info("Loading image...")
            image = Image.open(image_path)
            logger.info(f"Image loaded successfully. Size: {image.size}, Mode: {image.mode}")
            
            # Content Safety & Moderation Check
            logger.info("Performing content safety check...")
            is_safe, moderation_result = self.content_moderator.check_content_safety(image_path)
            
            if not is_safe:
                logger.warning(f"Content rejected due to: {moderation_result['rejection_reason']}")
                return {
                    'status': 'rejected',
                    'message': 'Image content was flagged as inappropriate',
                    'rejection_reason': moderation_result['rejection_reason'],
                    'moderation_details': moderation_result,
                    'final_score': 0,
                    'recommendations': [
                        'Please upload a different image that complies with our content guidelines',
                        'Ensure the image doesn\'t contain inappropriate, violent, or graphic content',
                        'Consider using images that are suitable for social media platforms'
                    ]
                }
            
            logger.info("Content safety check passed - proceeding with scoring")
            
            # Get all scores in one API call
            logger.info("Getting all scores in a single API call...")
            scores_result = self._get_all_scores_combined(image, user_preferences)
            
            # Calculate weighted final score
            logger.info("Calculating weighted final score...")
            final_score = (
                scores_result['technical_score'] * self.weights['technical_quality'] +
                scores_result['compositional_score'] * self.weights['compositional_strength'] +
                scores_result['psychological_score'] * self.weights['psychological_engagement'] +
                scores_result['trend_score'] * self.weights['trend_zeitgeist']
            )
            logger.info(f"Final weighted score: {final_score}")
            
            # Get detailed analyses in one API call
            logger.info("Getting detailed analyses...")
            details_result = self._get_all_details_combined(image, user_preferences)
            
            # Get recommendations
            logger.info("Generating recommendations...")
            recommendations = self._get_recommendations(image, final_score, user_preferences)
            
            result = {
                'final_score': round(final_score, 1),
                'technical_quality': {
                    'score': scores_result['technical_score'],
                    'weight': self.weights['technical_quality'],
                    'details': details_result['technical_details']
                },
                'compositional_strength': {
                    'score': scores_result['compositional_score'],
                    'weight': self.weights['compositional_strength'],
                    'details': details_result['compositional_details']
                },
                'psychological_engagement': {
                    'score': scores_result['psychological_score'],
                    'weight': self.weights['psychological_engagement'],
                    'details': details_result['psychological_details']
                },
                'trend_zeitgeist': {
                    'score': scores_result['trend_score'],
                    'weight': self.weights['trend_zeitgeist'],
                    'details': details_result['trend_details']
                },
                'recommendations': recommendations,
                'user_preferences_used': user_preferences if user_preferences else None,
                'content_moderation': {
                    'status': 'passed',
                    'details': moderation_result
                }
            }
            
            logger.info(f"Efficient analysis complete. Final score: {result['final_score']}/100")
            return result
            
        except Exception as e:
            logger.error(f"Efficient analysis failed with error: {str(e)}", exc_info=True)
            return {'error': f'Analysis failed: {str(e)}'}
    
    def _get_technical_quality_score(self, image: Image) -> float:
        """Get Technical Quality Score (25% weight)"""
        logger.info("Starting Technical Quality Score analysis...")
        
        prompt = """
        Analyze this image for technical quality. Consider:
        1. Sharpness & Focus (0-25 points): Is the image sharp and well-focused?
        2. Resolution & Clarity (0-25 points): Is the image clear and high-resolution?
        3. Image Noise (0-20 points): Is the image free from noise and artifacts?
        4. Dynamic Range (0-15 points): Are highlights and shadows well-balanced?
        5. Color Fidelity (0-15 points): Are colors natural and well-balanced?
        
        Return ONLY a raw JSON object (no markdown formatting, no code blocks) with:
        {
            "score": [0-100],
            "sharpness_focus": [0-25],
            "resolution_clarity": [0-25], 
            "noise": [0-20],
            "dynamic_range": [0-15],
            "color_fidelity": [0-15],
            "reasoning": "brief explanation"
        }
        """
        
        logger.info("Sending Technical Quality prompt to OpenAI...")
        response = self._get_openai_response(image, prompt)
        logger.info(f"OpenAI Technical Quality response: {response}")
        
        try:
            cleaned_response = self._clean_json_response(response)
            logger.info(f"Cleaned response: {cleaned_response}")
            
            result = json.loads(cleaned_response)
            score = result.get('score', 0)
            logger.info(f"Technical Quality Score parsed successfully: {score}")
            return score
        except json.JSONDecodeError as e:
            logger.error(f"Failed to parse Technical Quality JSON: {e}")
            logger.error(f"Raw response: {response}")
            logger.error(f"Cleaned response: {cleaned_response}")
            return 50  # Default score if parsing fails
    
    def _get_compositional_strength_score(self, image: Image) -> float:
        """Get Compositional Strength Score (25% weight)"""
        logger.info("Starting Compositional Strength Score analysis...")
        
        prompt = """
        Analyze this image for compositional strength. Consider:
        1. Rule of Thirds (0-25 points): Is the subject positioned according to rule of thirds?
        2. Leading Lines (0-20 points): Do lines guide the eye toward the subject?
        3. Balance & Symmetry (0-20 points): Is the composition balanced?
        4. Depth & Framing (0-20 points): Does the image have good depth and framing?
        5. Subject Isolation (0-15 points): Is the subject well-isolated and prominent?
        
        Return ONLY a raw JSON object (no markdown formatting, no code blocks) with:
        {
            "score": [0-100],
            "rule_of_thirds": [0-25],
            "leading_lines": [0-20],
            "balance_symmetry": [0-20],
            "depth_framing": [0-20],
            "subject_isolation": [0-15],
            "reasoning": "brief explanation"
        }
        """
        
        logger.info("Sending Compositional Strength prompt to OpenAI...")
        response = self._get_openai_response(image, prompt)
        logger.info(f"OpenAI Compositional Strength response: {response}")
        
        try:
            cleaned_response = self._clean_json_response(response)
            logger.info(f"Cleaned response: {cleaned_response}")
            
            result = json.loads(cleaned_response)
            score = result.get('score', 0)
            logger.info(f"Compositional Strength Score parsed successfully: {score}")
            return score
        except json.JSONDecodeError as e:
            logger.error(f"Failed to parse Compositional Strength JSON: {e}")
            logger.error(f"Raw response: {response}")
            logger.error(f"Cleaned response: {cleaned_response}")
            return 50
    
    def _get_psychological_engagement_score(self, image: Image) -> float:
        """Get Psychological Engagement Score (30% weight)"""
        logger.info("Starting Psychological Engagement Score analysis...")
        
        prompt = """
        Analyze this image for psychological engagement potential. Consider:
        1. Presence of Faces (0-30 points): Are there faces and are they engaging?
        2. Emotional Resonance (0-25 points): Does the image evoke emotions?
        3. Color Psychology (0-25 points): Do colors create the right mood?
        4. Storytelling (0-20 points): Does the image tell a story?
        
        Return ONLY a raw JSON object (no markdown formatting, no code blocks) with:
        {
            "score": [0-100],
            "faces": [0-30],
            "emotional_resonance": [0-25],
            "color_psychology": [0-25],
            "storytelling": [0-20],
            "reasoning": "brief explanation"
        }
        """
        
        logger.info("Sending Psychological Engagement prompt to OpenAI...")
        response = self._get_openai_response(image, prompt)
        logger.info(f"OpenAI Psychological Engagement response: {response}")
        
        try:
            cleaned_response = self._clean_json_response(response)
            logger.info(f"Cleaned response: {cleaned_response}")
            
            result = json.loads(cleaned_response)
            score = result.get('score', 0)
            logger.info(f"Psychological Engagement Score parsed successfully: {score}")
            return score
        except json.JSONDecodeError as e:
            logger.error(f"Failed to parse Psychological Engagement JSON: {e}")
            logger.error(f"Raw response: {response}")
            logger.error(f"Cleaned response: {cleaned_response}")
            return 50
    
    def _get_trend_zeitgeist_score(self, image: Image) -> float:
        """Get Trend & Zeitgeist Score (20% weight)"""
        logger.info("Starting Trend & Zeitgeist Score analysis...")
        
        prompt = """
        Analyze this image for trend alignment and zeitgeist. Consider:
        1. Aesthetic Alignment (0-60 points): Does it align with current visual trends?
        2. Authenticity Index (0-40 points): Does it feel authentic and genuine?
        
        Return ONLY a raw JSON object (no markdown formatting, no code blocks) with:
        {
            "score": [0-100],
            "aesthetic_alignment": [0-60],
            "authenticity": [0-40],
            "detected_aesthetic": "e.g., Y2K, Maximalist, Minimalist, etc.",
            "reasoning": "brief explanation"
        }
        """
        
        logger.info("Sending Trend & Zeitgeist prompt to OpenAI...")
        response = self._get_openai_response(image, prompt)
        logger.info(f"OpenAI Trend & Zeitgeist response: {response}")
        
        try:
            cleaned_response = self._clean_json_response(response)
            logger.info(f"Cleaned response: {cleaned_response}")
            
            result = json.loads(cleaned_response)
            score = result.get('score', 0)
            logger.info(f"Trend & Zeitgeist Score parsed successfully: {score}")
            return score
        except json.JSONDecodeError as e:
            logger.error(f"Failed to parse Trend & Zeitgeist JSON: {e}")
            logger.error(f"Raw response: {response}")
            logger.error(f"Cleaned response: {cleaned_response}")
            return 50
    
    def _get_all_scores_combined(self, image: Image, user_preferences: Optional[Dict] = None) -> Dict:
        """Get all scores in a single API call with personalization"""
        
        # Build personalized prompt based on user preferences
        if user_preferences:
            aesthetic = user_preferences.get('aesthetic', 'General')
            niche = user_preferences.get('niche', 'General')
            target_audience = user_preferences.get('target_audience', 'General')
            content_type = user_preferences.get('content_type', 'Social Media Post')
            brand_voice = user_preferences.get('brand_voice', 'Neutral')
            
            prompt = f"""
            Analyze this image for social media scoring with personalized criteria.
            
            USER PREFERENCES:
            - Aesthetic: {aesthetic}
            - Niche: {niche}
            - Target Audience: {target_audience}
            - Content Type: {content_type}
            - Brand Voice: {brand_voice}
            
            Score this image based on how well it aligns with the user's specific preferences above.
            
            Technical Quality (0-100): Sharpness, resolution, noise, dynamic range, color fidelity
            Compositional Strength (0-100): Rule of thirds, leading lines, balance, depth, subject isolation
            Psychological Engagement (0-100): Face detection, emotional resonance, color psychology, storytelling
            Trend & Zeitgeist (0-100): Alignment with {aesthetic} aesthetic for {niche} targeting {target_audience}
            
            Return ONLY a raw JSON object (no markdown formatting, no code blocks) with:
            {{
                "technical_score": [0-100],
                "compositional_score": [0-100],
                "psychological_score": [0-100],
                "trend_score": [0-100],
                "reasoning": "brief explanation considering user preferences"
            }}
            """
        else:
            prompt = """
            Analyze this image for social media scoring. Provide scores for all four categories in a single JSON response.
            
            Technical Quality (0-100): Sharpness, resolution, noise, dynamic range, color fidelity
            Compositional Strength (0-100): Rule of thirds, leading lines, balance, depth, subject isolation
            Psychological Engagement (0-100): Face detection, emotional resonance, color psychology, storytelling
            Trend & Zeitgeist (0-100): Aesthetic alignment, authenticity index
            
            Return ONLY a raw JSON object (no markdown formatting, no code blocks) with:
            {
                "technical_score": [0-100],
                "compositional_score": [0-100],
                "psychological_score": [0-100],
                "trend_score": [0-100],
                "reasoning": "brief overall explanation"
            }
            """
        
        logger.info("Sending combined scoring prompt to OpenAI...")
        response = self._get_openai_response(image, prompt)
        logger.info(f"OpenAI combined scoring response: {response}")
        
        try:
            cleaned_response = self._clean_json_response(response)
            logger.info(f"Cleaned combined response: {cleaned_response}")
            
            result = json.loads(cleaned_response)
            scores = {
                'technical_score': result.get('technical_score', 50),
                'compositional_score': result.get('compositional_score', 50),
                'psychological_score': result.get('psychological_score', 50),
                'trend_score': result.get('trend_score', 50)
            }
            logger.info(f"Combined scores parsed successfully: {scores}")
            return scores
        except json.JSONDecodeError as e:
            logger.error(f"Failed to parse combined scores JSON: {e}")
            logger.error(f"Raw response: {response}")
            return {
                'technical_score': 50,
                'compositional_score': 50,
                'psychological_score': 50,
                'trend_score': 50
            }
    
    def _get_all_details_combined(self, image: Image, user_preferences: Optional[Dict] = None) -> Dict:
        """Get all detailed analyses in a single API call with personalization"""
        
        # Build personalized prompt based on user preferences
        if user_preferences:
            aesthetic = user_preferences.get('aesthetic', 'General')
            niche = user_preferences.get('niche', 'General')
            target_audience = user_preferences.get('target_audience', 'General')
            
            prompt = f"""
            Provide detailed analysis for this image in four categories, considering the user's preferences:
            - Aesthetic: {aesthetic}
            - Niche: {niche}
            - Target Audience: {target_audience}
            
            Return as a JSON object with:
            
            - technical_details: Brief technical analysis focusing on sharpness, noise, and color quality
            - compositional_details: Brief compositional analysis focusing on framing, balance, and visual flow
            - psychological_details: Brief psychological analysis focusing on emotional impact and engagement potential for {target_audience}
            - trend_details: Brief trend analysis focusing on alignment with {aesthetic} aesthetic for {niche} content
            
            Return ONLY a raw JSON object (no markdown formatting, no code blocks) with:
            {{
                "technical_details": "brief technical analysis",
                "compositional_details": "brief compositional analysis", 
                "psychological_details": "brief psychological analysis",
                "trend_details": "brief trend analysis"
            }}
            """
        else:
            prompt = """
            Provide detailed analysis for this image in four categories. Return as a JSON object with:
            
            - technical_details: Brief technical analysis focusing on sharpness, noise, and color quality
            - compositional_details: Brief compositional analysis focusing on framing, balance, and visual flow
            - psychological_details: Brief psychological analysis focusing on emotional impact and engagement potential
            - trend_details: Brief trend analysis focusing on current aesthetic alignment and cultural relevance
            
            Return ONLY a raw JSON object (no markdown formatting, no code blocks) with:
            {
                "technical_details": "brief technical analysis",
                "compositional_details": "brief compositional analysis", 
                "psychological_details": "brief psychological analysis",
                "trend_details": "brief trend analysis"
            }
            """
        
        logger.info("Sending combined details prompt to OpenAI...")
        response = self._get_openai_response(image, prompt)
        logger.info(f"OpenAI combined details response: {response}")
        
        try:
            cleaned_response = self._clean_json_response(response)
            logger.info(f"Cleaned combined details response: {cleaned_response}")
            
            result = json.loads(cleaned_response)
            details = {
                'technical_details': result.get('technical_details', 'Technical analysis not available'),
                'compositional_details': result.get('compositional_details', 'Compositional analysis not available'),
                'psychological_details': result.get('psychological_details', 'Psychological analysis not available'),
                'trend_details': result.get('trend_details', 'Trend analysis not available')
            }
            logger.info(f"Combined details parsed successfully")
            return details
        except json.JSONDecodeError as e:
            logger.error(f"Failed to parse combined details JSON: {e}")
            logger.error(f"Raw response: {response}")
            return {
                'technical_details': 'Technical analysis not available',
                'compositional_details': 'Compositional analysis not available',
                'psychological_details': 'Psychological analysis not available',
                'trend_details': 'Trend analysis not available'
            }
    
    def _clean_json_response(self, response: str) -> str:
        """Clean JSON response by removing markdown formatting"""
        cleaned_response = response.strip()
        if cleaned_response.startswith('```json'):
            cleaned_response = cleaned_response[7:]  # Remove ```json
        if cleaned_response.startswith('```'):
            cleaned_response = cleaned_response[3:]  # Remove ```
        if cleaned_response.endswith('```'):
            cleaned_response = cleaned_response[:-3]  # Remove trailing ```
        
        return cleaned_response.strip()
    
    def _get_openai_response(self, image: Image, prompt: str) -> str:
        """Get response from OpenAI GPT-4 Vision"""
        logger.info("Preparing image for OpenAI API...")
        
        try:
            # Convert PIL image to base64
            img_buffer = io.BytesIO()
            image.save(img_buffer, format='JPEG')
            img_str = base64.b64encode(img_buffer.getvalue()).decode()
            logger.info(f"Image converted to base64. Size: {len(img_str)} characters")
            
            logger.info("Sending request to OpenAI API...")
            response = self.client.chat.completions.create(
                model="gpt-4o-mini",
                messages=[
                    {
                        "role": "user",
                        "content": [
                            {"type": "text", "text": prompt},
                            {
                                "type": "image_url",
                                "image_url": {
                                    "url": f"data:image/jpeg;base64,{img_str}"
                                }
                            }
                        ]
                    }
                ],
                max_tokens=500
            )
            
            content = response.choices[0].message.content
            logger.info(f"OpenAI API response received. Length: {len(content)} characters")
            logger.info(f"OpenAI API usage: {response.usage}")
            
            return content
            
        except Exception as e:
            logger.error(f"OpenAI API error: {e}", exc_info=True)
            return "{}"
    
    def _get_technical_details(self, image: Image) -> str:
        """Get detailed technical analysis"""
        logger.info("Getting detailed technical analysis...")
        prompt = "Provide a brief technical analysis of this image focusing on sharpness, noise, and color quality."
        response = self._get_openai_response(image, prompt)
        logger.info(f"Technical details received: {len(response)} characters")
        return response
    
    def _get_compositional_details(self, image: Image) -> str:
        """Get detailed compositional analysis"""
        logger.info("Getting detailed compositional analysis...")
        prompt = "Provide a brief compositional analysis of this image focusing on framing, balance, and visual flow."
        response = self._get_openai_response(image, prompt)
        logger.info(f"Compositional details received: {len(response)} characters")
        return response
    
    def _get_psychological_details(self, image: Image) -> str:
        """Get detailed psychological analysis"""
        logger.info("Getting detailed psychological analysis...")
        prompt = "Provide a brief psychological analysis of this image focusing on emotional impact and engagement potential."
        response = self._get_openai_response(image, prompt)
        logger.info(f"Psychological details received: {len(response)} characters")
        return response
    
    def _get_trend_details(self, image: Image) -> str:
        """Get detailed trend analysis"""
        logger.info("Getting detailed trend analysis...")
        prompt = "Provide a brief trend analysis of this image focusing on current aesthetic alignment and cultural relevance."
        response = self._get_openai_response(image, prompt)
        logger.info(f"Trend details received: {len(response)} characters")
        return response
    
    def _get_recommendations(self, image: Image, final_score: float, user_preferences: Optional[Dict] = None) -> List[str]:
        """Get improvement recommendations based on score"""
        logger.info(f"Generating recommendations for score: {final_score}")
        
        # Build personalized prompt based on user preferences
        if user_preferences:
            aesthetic = user_preferences.get('aesthetic', 'General')
            niche = user_preferences.get('niche', 'General')
            target_audience = user_preferences.get('target_audience', 'General')
            content_type = user_preferences.get('content_type', 'Social Media Post')
            brand_voice = user_preferences.get('brand_voice', 'Neutral')
            
            prompt = f"""
            This image received a social media score of {final_score}/100. 
            Provide 3 specific, actionable recommendations to improve the score, considering the user's preferences:
            - Aesthetic: {aesthetic}
            - Niche: {niche}
            - Target Audience: {target_audience}
            - Content Type: {content_type}
            - Brand Voice: {brand_voice}
            Focus on practical tips that could be implemented quickly.
            """
        else:
            prompt = f"""
            This image received a social media score of {final_score}/100. 
            Provide 3 specific, actionable recommendations to improve the score.
            Focus on practical tips that could be implemented quickly.
            """
        
        response = self._get_openai_response(image, prompt)
        logger.info(f"Recommendations response: {response}")
        
        # Parse recommendations more intelligently
        lines = response.split('\n')
        recommendations = []
        current_recommendation = ""
        
        for line in lines:
            line = line.strip()
            # Look for numbered recommendations (1., 2., 3., etc.)
            if line and (line.startswith('1.') or line.startswith('2.') or line.startswith('3.') or 
                        line.startswith('**1.') or line.startswith('**2.') or line.startswith('**3.')):
                # If we have a previous recommendation, save it
                if current_recommendation:
                    recommendations.append(current_recommendation.strip())
                
                # Start new recommendation
                clean_line = line.replace('**', '').strip()
                if clean_line.startswith('1.'):
                    current_recommendation = clean_line[2:].strip()
                elif clean_line.startswith('2.'):
                    current_recommendation = clean_line[2:].strip()
                elif clean_line.startswith('3.'):
                    current_recommendation = clean_line[2:].strip()
                else:
                    current_recommendation = clean_line
            elif line and current_recommendation and not line.startswith('To improve') and not line.startswith('Implementing'):
                # Continue building the current recommendation
                current_recommendation += " " + line
        
        # Add the last recommendation
        if current_recommendation:
            recommendations.append(current_recommendation.strip())
        
        # If we didn't find numbered recommendations, try a simpler approach
        if len(recommendations) < 3:
            recommendations = [line.strip() for line in lines if line.strip() and 
                             not line.startswith('To improve') and 
                             not line.startswith('Implementing') and
                             len(line.strip()) > 20][:3]
        
        logger.info(f"Parsed {len(recommendations)} recommendations")
        
        return recommendations

# Test function
def test_scorer():
    """Test the scorer with a sample image"""
    logger.info("Starting test_scorer function...")
    scorer = ViralVelocityScorer()
    
    # You'll need to provide a test image path
    test_image_path = "test_image.jpg"  # Replace with actual image path
    
    if os.path.exists(test_image_path):
        logger.info(f"Test image found: {test_image_path}")
        result = scorer.analyze_image(test_image_path)
        logger.info("Test completed successfully")
        print(json.dumps(result, indent=2))
    else:
        logger.warning(f"Test image not found: {test_image_path}")
        print(f"Test image not found: {test_image_path}")
        print("Please provide a test image to run the scorer.")

if __name__ == "__main__":
    test_scorer()
