import json
import platform
from pathlib import Path

class SettingsManager:
    """
    Centralizes access to application settings to prevent conflicts between components.
    """
    
    @staticmethod
    def get_settings_file_path(filename="settings.json"):
        """Get the platform-specific path for the settings file."""
        if platform.system() == 'Darwin':  # macOS
            from utils.api_key_manager import APIKeyManager
            mac_path = APIKeyManager.get_app_support_path_mac()
            return f"{mac_path}/{filename}"
        else:
            return filename  # Default to current directory for non-macOS systems
    
    @classmethod
    def get_default_settings(cls):
        """Return the default settings structure."""
        return {
            "chat_gpt_completion": False,
            "model": "gpt-4o-mini",
            "prompt": "",
            "auto_apply_ai_to_recording": False,
            "hide_banner": False,
            "auto_check_version": True,
            "current_tone": "None",
            "input_device": "Default",
            "primary_device": "Select Device",
            "secondary_device": "None",
            "hotkeys": {
                "record_start_stop": ["ctrl", "shift", "0"],
                "stop_recording": ["ctrl", "shift", "9"],
                "play_last_audio": ["ctrl", "shift", "8"],
                "cancel_operation": ["ctrl", "shift", "1"]
            },
            "max_tokens": 750
        }
    
    @classmethod
    def load_settings(cls):
        """Load settings from file, with defaults for missing values."""
        settings_file = cls.get_settings_file_path()
        default_settings = cls.get_default_settings()
        
        try:
            # Try to load existing settings
            with open(settings_file, "r") as f:
                settings = json.load(f)
                
            # Check if settings need to be updated with new defaults
            settings_updated = False
            
            # Recursively update nested dictionaries with missing keys
            def update_missing_settings(existing, defaults):
                nonlocal settings_updated
                for key, value in defaults.items():
                    if key not in existing:
                        existing[key] = value
                        settings_updated = True
                    elif isinstance(value, dict) and isinstance(existing[key], dict):
                        # Recursively update nested dictionaries
                        update_missing_settings(existing[key], value)
                return existing
            
            # Update settings with any missing values
            settings = update_missing_settings(settings, default_settings)
            
            # Save if any settings were updated
            if settings_updated:
                cls.save_settings(settings)
                print("Settings file updated with new default values")
                
        except FileNotFoundError:
            # Create new settings file with defaults if it doesn't exist
            settings = default_settings
            cls.save_settings(settings)
        
        return settings
    
    @classmethod
    def save_settings(cls, settings):
        """Save complete settings to file."""
        settings_file = cls.get_settings_file_path()
        
        with open(settings_file, "w") as f:
            json.dump(settings, f, indent=4)
    
    @classmethod
    def update_settings(cls, partial_settings):
        """
        Update only specific settings without touching others.
        
        Args:
            partial_settings: Dictionary containing only the settings to update
        """
        # First load existing settings
        current_settings = cls.load_settings()
        
        # Update settings (recursively for nested dictionaries)
        def recursive_update(target, source):
            for key, value in source.items():
                if isinstance(value, dict) and key in target and isinstance(target[key], dict):
                    # If both are dictionaries, update recursively
                    recursive_update(target[key], value)
                else:
                    # Otherwise just update the value
                    target[key] = value
        
        recursive_update(current_settings, partial_settings)
        
        # Save the updated settings
        cls.save_settings(current_settings)
        return current_settings 