#!/usr/bin/env python3
"""
User Profile Integration Module
Provides integration between games and the user profile system
"""

import json
import uuid
import platform
import hashlib
from datetime import datetime
from score_api_client import ScoreAPIClient


class UserProfileIntegration:
    """Integration layer between the game and profile system"""
    
    def __init__(self, profiles_file="user_profiles.json", api_url="http://172.27.23.245:8000"):
        self.profiles_file = profiles_file
        self.current_profile = None
        self.device_id = self.generate_device_id()
        self.api_client = ScoreAPIClient(api_url)
        self.api_enabled = self.api_client.is_server_available()
        self.load_active_profile()
        
        if self.api_enabled:
            print(f"✓ Connected to score server at {api_url}")
        else:
            print(f"✗ Score server not available at {api_url} - running offline")
    
    def generate_device_id(self):
        """Generate a unique device ID based on system information"""
        # Get system information
        system_info = f"{platform.system()}-{platform.machine()}-{platform.processor()}"
        
        # Try to get MAC address for more uniqueness
        try:
            mac = ':'.join(['{:02x}'.format((uuid.getnode() >> ele) & 0xff) 
                           for ele in range(0,8*6,8)][::-1])
            system_info += f"-{mac}"
        except:
            pass
        
        # Create hash and take first 8 characters
        device_hash = hashlib.md5(system_info.encode()).hexdigest()[:8].upper()
        return f"DEV-{device_hash}"
    
    def load_active_profile(self):
        """Load the currently active profile"""
        try:
            with open(self.profiles_file, 'r') as f:
                data = json.load(f)
                active_name = data.get('active_profile')
                if active_name and active_name in data['profiles']:
                    self.current_profile = data['profiles'][active_name]
                    print(f"Loaded profile: {self.current_profile['name']}")
                    
                    # Sync with API if available
                    if self.api_enabled:
                        self.sync_profile_with_api()
                    
                    return True
        except (FileNotFoundError, json.JSONDecodeError) as e:
            print(f"Could not load profile: {e}")
        
        self.current_profile = None
        return False
    
    def get_profile_name(self):
        """Get current profile name or default"""
        return self.current_profile['name'] if self.current_profile else "Guest Player"
    
    def get_device_id(self):
        """Get the unique device identifier"""
        return self.device_id
    
    def get_setting(self, setting_name, default_value=None):
        """Get a setting from the current profile, or return default"""
        if self.current_profile and 'settings' in self.current_profile:
            return self.current_profile['settings'].get(setting_name, default_value)
        return default_value
    
    def sync_profile_with_api(self):
        """Ensure current profile is registered with the API server"""
        if not self.current_profile or not self.api_enabled:
            return False
        
        profile_name = self.current_profile['name']
        
        # Check if user exists on server
        if not self.api_client.user_exists(self.device_id, profile_name):
            print(f"Registering {profile_name} with score server...")
            result = self.api_client.signup_user(self.device_id, profile_name)
            if result.get('success'):
                print(f"✓ {profile_name} registered successfully")
                return True
            else:
                print(f"✗ Failed to register {profile_name}: {result.get('message')}")
                return False
        else:
            print(f"✓ {profile_name} already registered on server")
            return True
    
    def register_new_user(self, user_id):
        """Register a new user both locally and on the API server"""
        if not self.api_enabled:
            print("API server not available - user will only be registered locally")
            return True
        
        result = self.api_client.signup_user(self.device_id, user_id)
        if result.get('success'):
            print(f"✓ {user_id} registered with server successfully")
            return True
        else:
            print(f"✗ Failed to register {user_id} with server: {result.get('message')}")
            return False
    
    def update_game_stats(self, score, completed=True):
        """Update the current profile's game statistics"""
        if not self.current_profile:
            print("No profile loaded - stats not saved")
            return False
        
        # Submit score to API first if available
        if self.api_enabled:
            profile_name = self.current_profile['name']
            result = self.api_client.submit_score(
                self.device_id, 
                profile_name, 
                score, 
                completed
            )
            if result.get('success'):
                print(f"✓ Score {score} submitted to server successfully")
                # Print server stats if available
                if 'user_stats' in result:
                    stats = result['user_stats']
                    print(f"  Server stats - Games: {stats['total_games']}, Best: {stats['best_score']}")
            else:
                print(f"✗ Failed to submit score to server: {result.get('message')}")
        
        try:
            # Update local profile
            with open(self.profiles_file, 'r') as f:
                data = json.load(f)
            
            profile_name = self.current_profile['name']
            if profile_name in data['profiles']:
                profile = data['profiles'][profile_name]
                
                # Update statistics
                if completed:
                    profile['games_played'] += 1
                    print(f"Game completed for {profile_name}! Total games: {profile['games_played']}")
                
                profile['total_score'] += score
                if score > profile['best_score']:
                    profile['best_score'] = score
                    print(f"New best score for {profile_name}: {score}!")
                
                profile['last_played'] = datetime.now().isoformat()
                
                # Update our local copy
                self.current_profile = profile
                
                # Save back to file
                with open(self.profiles_file, 'w') as f:
                    json.dump(data, f, indent=2)
                
                print(f"Local profile stats updated: Score +{score}, Total: {profile['total_score']}")
                return True
                
        except Exception as e:
            print(f"Error updating profile stats: {e}")
        
        return False
    
    def add_achievement(self, achievement_id):
        """Add an achievement to the current profile"""
        if not self.current_profile:
            return False
        
        try:
            with open(self.profiles_file, 'r') as f:
                data = json.load(f)
            
            profile_name = self.current_profile['name']
            if profile_name in data['profiles']:
                profile = data['profiles'][profile_name]
                
                if achievement_id not in profile['achievements']:
                    profile['achievements'].append(achievement_id)
                    self.current_profile = profile
                    
                    with open(self.profiles_file, 'w') as f:
                        json.dump(data, f, indent=2)
                    
                    print(f"Achievement unlocked for {profile_name}: {achievement_id}")
                    return True
                    
        except Exception as e:
            print(f"Error adding achievement: {e}")
        
        return False
    
    def get_profile_info(self):
        """Get current profile information for display"""
        if self.current_profile:
            info = {
                'name': self.current_profile['name'],
                'games_played': self.current_profile['games_played'],
                'best_score': self.current_profile['best_score'],
                'total_score': self.current_profile['total_score'],
                'achievements': len(self.current_profile['achievements']),
                'difficulty': self.current_profile['settings'].get('difficulty', 'normal'),
                'device_id': self.device_id,
                'api_connected': self.api_enabled
            }
            return info
        return None
    
    def get_device_leaderboard(self, limit=10):
        """Get leaderboard for the current device from API server"""
        if not self.api_enabled:
            print("API server not available - cannot get leaderboard")
            return []
        
        leaderboard = self.api_client.get_leaderboard(self.device_id, limit)
        return leaderboard
    
    def get_global_leaderboard(self, limit=10):
        """Get global leaderboard across all devices from API server"""
        if not self.api_enabled:
            print("API server not available - cannot get global leaderboard")
            return []
        
        leaderboard = self.api_client.get_global_leaderboard(limit)
        return leaderboard
    
    def get_all_device_users(self):
        """Get all users registered for this device from API server"""
        if not self.api_enabled:
            print("API server not available - cannot get user list")
            return []
        
        users = self.api_client.get_device_users(self.device_id)
        return users
    
    def get_user_server_scores(self, user_id=None, limit=10):
        """Get recent scores from server for a user (defaults to current profile)"""
        if not self.api_enabled:
            return []
        
        if user_id is None:
            if not self.current_profile:
                return []
            user_id = self.current_profile['name']
        
        scores = self.api_client.get_user_scores(self.device_id, user_id, limit)
        return scores
    
    def reload_profile(self):
        """Reload the current profile from disk (useful for external profile changes)"""
        return self.load_active_profile()


# Convenience functions for quick integration
def get_active_profile():
    """Quick function to get active profile info"""
    integration = UserProfileIntegration()
    return integration.get_profile_info()

def update_profile_score(score, completed=True):
    """Quick function to update profile score"""
    integration = UserProfileIntegration()
    return integration.update_game_stats(score, completed)

def get_profile_setting(setting_name, default_value=None):
    """Quick function to get a profile setting"""
    integration = UserProfileIntegration()
    return integration.get_setting(setting_name, default_value)

def get_device_leaderboard(limit=10):
    """Quick function to get device leaderboard"""
    integration = UserProfileIntegration()
    return integration.get_device_leaderboard(limit)

def get_global_leaderboard(limit=10):
    """Quick function to get global leaderboard"""
    integration = UserProfileIntegration()
    return integration.get_global_leaderboard(limit)


if __name__ == "__main__":
    # Test the integration
    print("Testing User Profile Integration with API...")
    
    integration = UserProfileIntegration()
    print(f"Device ID: {integration.get_device_id()}")
    print(f"Profile Name: {integration.get_profile_name()}")
    print(f"API Connected: {integration.api_enabled}")
    
    info = integration.get_profile_info()
    if info:
        print(f"Profile Info: {info}")
    else:
        print("No profile loaded")
    
    # Test settings
    difficulty = integration.get_setting('difficulty', 'normal')
    sound_volume = integration.get_setting('sound_volume', 50)
    print(f"Settings - Difficulty: {difficulty}, Sound: {sound_volume}%")
    
    # Test API features if connected
    if integration.api_enabled:
        print("\nTesting API features...")
        
        # Get leaderboard
        leaderboard = integration.get_device_leaderboard(5)
        if leaderboard:
            print("Device Leaderboard:")
            for entry in leaderboard:
                print(f"  {entry['rank']}. {entry['user_id']}: {entry['best_score']} pts ({entry['total_games']} games)")
        else:
            print("No leaderboard data available")
        
        # Get all users
        users = integration.get_all_device_users()
        print(f"\nTotal users on device: {len(users)}")
        for user in users:
            print(f"  {user['user_id']}: Best {user['best_score']}, {user['total_scores']} games")
        
        # Test score submission
        if integration.current_profile:
            print(f"\nTesting score submission for {integration.current_profile['name']}...")
            result = integration.update_game_stats(1234, True)
            print(f"Score update result: {result}")
    else:
        print("API features not available - server offline")
