"""
T228: VST Plugin Support
Soporte nativo para plugins VST dentro de capas
"""

import json
import os
from typing import Dict, List, Any, Optional
from dataclasses import dataclass


@dataclass
class VSTPlugin:
    """Configuración de plugin VST."""
    name: str
    vendor: str
    type: str  # 'instrument', 'effect'
    format: str  # 'VST2', 'VST3', 'AU'
    parameters: Dict[str, float]
    preset_name: Optional[str] = None
    is_enabled: bool = True


class VSTPluginManager:
    """
    Gestor de plugins VST para AbletonMCP-AI.
    
    T228: Soporte nativo de plugins VST dentro de capas.
    """
    
    # Plugins preconfigurados por género
    GENRE_PLUGINS = {
        'techno': {
            'instruments': [
                {'name': 'Serum', 'vendor': 'Xfer', 'preset_category': 'bass'},
                {'name': 'Diva', 'vendor': 'U-he', 'preset_category': 'pad'},
            ],
            'effects': [
                {'name': 'Pro-Q 3', 'vendor': 'FabFilter', 'role': 'eq'},
                {'name': 'Pro-C 2', 'vendor': 'FabFilter', 'role': 'compression'},
                {'name': 'Decapitator', 'vendor': 'Soundtoys', 'role': 'saturation'},
                {'name': 'EchoBoy', 'vendor': 'Soundtoys', 'role': 'delay'},
            ]
        },
        'house': {
            'instruments': [
                {'name': 'Sylenth1', 'vendor': 'LennarDigital', 'preset_category': 'lead'},
                {'name': 'Spire', 'vendor': 'Reveal Sound', 'preset_category': 'chord'},
            ],
            'effects': [
                {'name': 'Pro-Q 3', 'vendor': 'FabFilter', 'role': 'eq'},
                {'name': 'ValhallaVintageVerb', 'vendor': 'Valhalla', 'role': 'reverb'},
                {'name': 'OTT', 'vendor': 'Xfer', 'role': 'compression'},
            ]
        },
        'trance': {
            'instruments': [
                {'name': 'Serum', 'vendor': 'Xfer', 'preset_category': 'supersaw'},
                {'name': 'Sylenth1', 'vendor': 'LennarDigital', 'preset_category': 'lead'},
            ],
            'effects': [
                {'name': 'Pro-Q 3', 'vendor': 'FabFilter', 'role': 'eq'},
                {'name': 'ValhallaSupermassive', 'vendor': 'Valhalla', 'role': 'space'},
                {'name': 'ShaperBox', 'vendor': 'Cableguys', 'role': 'modulation'},
            ]
        }
    }
    
    def __init__(self):
        self.available_plugins = self._scan_available_plugins()
        self.layer_assignments = {}
    
    def _scan_available_plugins(self) -> Dict[str, List[VSTPlugin]]:
        """Escanea plugins VST disponibles."""
        # En producción, escanearía los directorios de plugins
        # Esta es una lista de plugins comunes conocidos
        
        known_plugins = [
            VSTPlugin('Serum', 'Xfer', 'instrument', 'VST3', 
                     {'osc1_wt_pos': 0.5, 'filter_cutoff': 0.7, 'env1_attack': 0.01}),
            VSTPlugin('Sylenth1', 'LennarDigital', 'instrument', 'VST2',
                     {'cutoff_a': 0.8, 'resonance_a': 0.3, 'attack_a': 0.02}),
            VSTPlugin('Pro-Q 3', 'FabFilter', 'effect', 'VST3',
                     {'output_gain': 0.0, 'processing_mode': 1.0}),
            VSTPlugin('Decapitator', 'Soundtoys', 'effect', 'VST2',
                     {'drive': 0.5, 'tone': 0.5, 'mix': 0.3}),
            VSTPlugin('ValhallaVintageVerb', 'Valhalla', 'effect', 'VST2',
                     {'mix': 0.25, 'decay': 0.6, 'color': 0.5}),
        ]
        
        return {
            'instruments': [p for p in known_plugins if p.type == 'instrument'],
            'effects': [p for p in known_plugins if p.type == 'effect']
        }
    
    def get_plugins_for_layer(self, layer_type: str, genre: str) -> Dict[str, Any]:
        """
        Obtiene configuración de plugins para una capa.
        
        Args:
            layer_type: 'drums', 'bass', 'music', 'fx'
            genre: Género musical
            
        Returns:
            Configuración de plugins para la capa
        """
        genre_plugins = self.GENRE_PLUGINS.get(genre, self.GENRE_PLUGINS['techno'])
        
        config = {
            'layer_type': layer_type,
            'genre': genre,
            'instruments': [],
            'effects_chain': []
        }
        
        if layer_type == 'bass':
            # Bass: Sintetizador + EQ + Compresión + Saturación
            config['instruments'] = [
                self._find_plugin_by_category('instruments', 'bass', genre_plugins)
            ]
            config['effects_chain'] = [
                {'name': 'Pro-Q 3', 'position': 'first', 'settings': {'low_cut': 30}},
                {'name': 'Pro-C 2', 'position': 'middle', 'settings': {'ratio': 4.0}},
                {'name': 'Decapitator', 'position': 'last', 'settings': {'drive': 0.4}}
            ]
        
        elif layer_type == 'music':
            # Music: Pad/Lead + EQ + Reverb + Delay
            config['instruments'] = [
                self._find_plugin_by_category('instruments', 'pad', genre_plugins)
            ]
            config['effects_chain'] = [
                {'name': 'Pro-Q 3', 'position': 'first', 'settings': {}},
                {'name': 'ValhallaVintageVerb', 'position': 'middle', 'settings': {'mix': 0.3}},
                {'name': 'EchoBoy', 'position': 'last', 'settings': {'mix': 0.2}}
            ]
        
        elif layer_type == 'drums':
            # Drums: EQ + Compresión (normalmente samples, no VST)
            config['effects_chain'] = [
                {'name': 'Pro-Q 3', 'position': 'first', 'settings': {'low_cut': 40}},
                {'name': 'Pro-C 2', 'position': 'last', 'settings': {'ratio': 2.0}}
            ]
        
        elif layer_type == 'fx':
            # FX: Efectos creativos
            config['effects_chain'] = [
                {'name': 'ValhallaSupermassive', 'position': 'only', 'settings': {'mix': 0.5}}
            ]
        
        return config
    
    def _find_plugin_by_category(self, plugin_type: str, category: str, 
                                  genre_plugins: Dict) -> Optional[Dict]:
        """Busca plugin por categoría."""
        plugins = genre_plugins.get(plugin_type, [])
        
        for plugin in plugins:
            if plugin.get('preset_category') == category:
                return {
                    'name': plugin['name'],
                    'vendor': plugin['vendor'],
                    'category': category
                }
        
        # Fallback al primero
        if plugins:
            return {
                'name': plugins[0]['name'],
                'vendor': plugins[0]['vendor'],
                'category': 'default'
            }
        
        return None
    
    def create_vst_layer_config(self, track_index: int, 
                              layer_type: str,
                              genre: str,
                              insert_position: int = 0) -> Dict[str, Any]:
        """
        Crea configuración completa de capa con VST.
        
        Args:
            track_index: Índice del track en Ableton
            layer_type: Tipo de capa
            genre: Género musical
            insert_position: Posición de inserción
            
        Returns:
            Configuración completa de la capa
        """
        plugin_config = self.get_plugins_for_layer(layer_type, genre)
        
        return {
            'track_index': track_index,
            'layer_type': layer_type,
            'insert_position': insert_position,
            'devices': self._generate_device_chain(plugin_config),
            'routing': {
                'input': 'ext_in',
                'output': 'master',
                'sends': {'Reverb': 0.3, 'Delay': 0.2} if layer_type == 'music' else {}
            },
            'automation': self._generate_automation_config(layer_type),
            'plugin_config': plugin_config
        }
    
    def _generate_device_chain(self, config: Dict) -> List[Dict]:
        """Genera cadena de dispositivos."""
        devices = []
        
        # Instrumento (si aplica)
        for instrument in config.get('instruments', []):
            if instrument:
                devices.append({
                    'type': 'vst_instrument',
                    'name': instrument['name'],
                    'vendor': instrument['vendor'],
                    'enabled': True
                })
        
        # Efectos
        for effect in config.get('effects_chain', []):
            devices.append({
                'type': 'vst_effect',
                'name': effect['name'],
                'position': effect.get('position', 'middle'),
                'settings': effect.get('settings', {}),
                'enabled': True
            })
        
        return devices
    
    def _generate_automation_config(self, layer_type: str) -> Dict[str, Any]:
        """Genera configuración de automatización."""
        if layer_type == 'bass':
            return {
                'filter_cutoff': {'device': 0, 'param': 'cutoff'},
                'volume': {'device': 'mixer', 'param': 'volume'}
            }
        elif layer_type == 'music':
            return {
                'reverb_wet': {'device': 1, 'param': 'mix'},
                'delay_feedback': {'device': 2, 'param': 'feedback'}
            }
        return {}
    
    def export_plugin_chain_preset(self, config: Dict, 
                                   filepath: str) -> Dict[str, Any]:
        """Exporta cadena de plugins como preset."""
        preset = {
            'version': '1.0',
            'type': 'plugin_chain',
            'config': config,
            'exported_at': datetime.now().isoformat()
        }
        
        with open(filepath, 'w') as f:
            json.dump(preset, f, indent=2)
        
        return {
            'success': True,
            'filepath': filepath,
            'devices_count': len(config.get('devices', []))
        }


def configure_vst_layer(track_index: int, layer_type: str, 
                        genre: str = 'techno') -> Dict[str, Any]:
    """
    T228: Configura capa con plugins VST.
    
    Args:
        track_index: Índice del track
        layer_type: Tipo de capa (drums, bass, music, fx)
        genre: Género musical
        
    Returns:
        Configuración de la capa VST
    """
    manager = VSTPluginManager()
    return manager.create_vst_layer_config(track_index, layer_type, genre)


if __name__ == '__main__':
    # Test del manager VST
    manager = VSTPluginManager()
    
    for layer in ['drums', 'bass', 'music', 'fx']:
        config = manager.get_plugins_for_layer(layer, 'techno')
        print(f"\n=== {layer.upper()} ===")
        print(json.dumps(config, indent=2))
