"""
Agente 17: Section Generator (Section-Based Composition)

This module provides section-based composition functions for generating
complete song sections (intro, build, breakdown, chorus, outro, verse)
and full song structures.

These functions return JSON-serializable dicts and are designed to be
called from server.py MCP tools.

NOTE: This file was originally written with @mcp.tool() decorators
but has been converted to plain functions to avoid circular imports
and undefined references. The MCP server (server.py) wraps these
functions as tools.
"""

import json
import logging
from typing import Dict, Any, Optional

logger = logging.getLogger("Agente17")


def _ok(data: Dict[str, Any]) -> str:
    """Return a success JSON string."""
    return json.dumps({"status": "success", **data})


def _err(message: str) -> str:
    """Return an error JSON string."""
    return json.dumps({"status": "error", "message": message})


def generate_section_by_type(
    at_bar: int = 0,
    duration_bars: int = 8,
    key: str = "Am",
    bpm: float = 95.0,
    build_method: str = "gradual",
    riser_type: str = "standard",
    drum_fill_intensity: float = 0.8,
    melodic_focus: bool = True,
    drum_reduction: float = 0.7,
    max_energy: bool = True,
    all_elements: bool = True,
    variation_type: str = "standard",
    recap_type: str = "melody_only",
    ending_style: str = "fade"
) -> str:
    """Genera una sección musical completa por tipo (Agente 17).
    
    Este tool crea configuraciones completas para diferentes tipos de secciones
    musicales: intro, build, breakdown, chorus, outro, y verse.
    
    Args:
        section_type: Tipo de sección - "intro", "build", "breakdown", "chorus", "outro", "verse"
        at_bar: Posición inicial en compases (default 0)
        duration_bars: Duración en compases (default 8)
        key: Tonalidad musical (default "Am")
        bpm: Tempo en BPM (default 95.0)
        build_method: Para intro - "gradual", "sudden", "ambient", "rhythmic"
        riser_type: Para build - "standard", "noise", "synth", "vocal", "minimal"
        drum_fill_intensity: Para build - intensidad 0.0-1.0 (default 0.8)
        melodic_focus: Para breakdown - enfocar en melodía (default True)
        drum_reduction: Para breakdown - reducción 0.0-1.0 (default 0.7)
        max_energy: Para chorus - máxima energía (default True)
        all_elements: Para chorus - incluir todos los elementos (default True)
        variation_type: Para chorus - "standard", "minimal", "double", "bouncy"
        recap_type: Para outro - "full", "melody_only", "drums_only", "chords_only"
        ending_style: Para outro - "fade", "cut", "breakdown", "loop"
    
    Returns:
        JSON con configuración completa de la sección generada.
        
    Examples:
        # Generar intro gradual de 8 compases
        generate_section_by_type(section_type="intro", at_bar=0, duration_bars=8, build_method="gradual")
        
        # Generar build con riser synth de 8 compases
        generate_section_by_type(section_type="build", at_bar=8, duration_bars=8, riser_type="synth", drum_fill_intensity=0.9)
        
        # Generar breakdown melódico de 8 compases
        generate_section_by_type(section_type="breakdown", at_bar=16, duration_bars=8, melodic_focus=True)
        
        # Generar chorus de 16 compases con máxima energía
        generate_section_by_type(section_type="chorus", at_bar=24, duration_bars=16, max_energy=True, variation_type="standard")
        
        # Generar outro con fade de 8 compases
        generate_section_by_type(section_type="outro", at_bar=40, duration_bars=8, recap_type="melody_only", ending_style="fade")
    """
    try:
        # Importar SectionGenerator
        from engines.section_generator import SectionGenerator, get_section_generator
        
        # Obtener o crear generador
        generator = get_section_generator(key=key, bpm=bpm)
        
        # Generar configuración según tipo
        config = None
        
        if section_type.lower() == "intro":
            config = generator.generate_intro(
                build_method=build_method,
                duration=duration_bars,
                start_with_drums=False,
                include_fx_riser=True
            )
        elif section_type.lower() == "build":
            config = generator.generate_build(
                riser_type=riser_type,
                drum_fill_intensity=drum_fill_intensity,
                duration=duration_bars,
                filter_sweep=True
            )
        elif section_type.lower() == "breakdown":
            config = generator.generate_breakdown(
                melodic_focus=melodic_focus,
                drum_reduction=drum_reduction,
                duration=duration_bars,
                include_buildup=True
            )
        elif section_type.lower() == "chorus":
            config = generator.generate_chorus(
                max_energy=max_energy,
                all_elements=all_elements,
                duration=duration_bars,
                variation_type=variation_type
            )
        elif section_type.lower() == "outro":
            config = generator.generate_outro(
                recap_type=recap_type,
                ending_style=ending_style,
                duration=duration_bars,
                include_melody=True
            )
        elif section_type.lower() == "verse":
            config = generator.generate_verse(
                variation="standard",
                duration=duration_bars,
                include_melody=False
            )
        else:
            return _err(f"Unknown section type: {section_type}. Valid types: intro, build, breakdown, chorus, outro, verse")
        
        # Ajustar posiciones para at_bar
        adjusted_tracks = []
        for track in config.tracks:
            adjusted_track = track.copy()
            adjusted_track["start_bar"] = at_bar + track.get("start_bar", 0)
            adjusted_tracks.append(adjusted_track)
        
        adjusted_fx = []
        for fx in config.fx:
            adjusted_fx_item = fx.copy()
            adjusted_fx_item["start_bar"] = at_bar + fx.get("start_bar", 0)
            adjusted_fx.append(adjusted_fx_item)
        
        adjusted_automations = []
        for auto in config.automations:
            adjusted_auto = auto.copy()
            adjusted_auto["start_bar"] = at_bar + auto.get("start_bar", 0)
            adjusted_auto["end_bar"] = at_bar + auto.get("end_bar", duration_bars)
            adjusted_automations.append(adjusted_auto)
        
        return _ok({
            "section_type": section_type,
            "start_bar": at_bar,
            "duration_bars": duration_bars,
            "key": key,
            "bpm": bpm,
            "energy_level": config.energy_level,
            "tracks": adjusted_tracks,
            "fx": adjusted_fx,
            "automations": adjusted_automations,
            "status": "generated",
            "note": f"Section '{section_type}' generated at bar {at_bar}. Use create_section_at_bar() to place in Arrangement View."
        })
        
    except ImportError:
        return _err("SectionGenerator engine not available. Check that section_generator.py is properly installed.")
    except Exception as e:
        return _err(f"Error generating section: {str(e)}")


def create_full_song_sections(
    structure_type: str = "standard",
    key: str = "Am",
    bpm: float = 95.0,
    start_bar: int = 0
) -> str:
    """Crea una estructura completa de canción con secciones (Agente 17).
    
    Genera una secuencia completa de secciones: intro, verse, chorus, etc.
    según el tipo de estructura solicitado.
    
    Args:
        structure_type: Tipo de estructura - "standard", "extended", "minimal"
        key: Tonalidad musical (default "Am")
        bpm: Tempo en BPM (default 95.0)
        start_bar: Barra inicial (default 0)
    
    Returns:
        JSON con lista de secciones generadas y sus configuraciones.
        
    Examples:
        # Estructura estándar
        create_full_song_sections(structure_type="standard", key="Am", bpm=95)
        
        # Estructura extendida
        create_full_song_sections(structure_type="extended", key="Dm", bpm=100)
    """
    try:
        from engines.section_generator import SectionGenerator, get_section_generator
        
        generator = get_section_generator(key=key, bpm=bpm)
        
        # Generar estructura completa
        sections = generator.create_full_song_structure(
            structure_type=structure_type,
            total_duration=64
        )
        
        # Convertir a diccionarios y ajustar posiciones
        results = []
        current_bar = start_bar
        
        for section in sections:
            result = {
                "section_type": section.section_type,
                "start_bar": current_bar,
                "duration_bars": section.duration_bars,
                "energy_level": section.energy_level,
                "key": section.key,
                "tracks_count": len(section.tracks),
                "fx_count": len(section.fx),
                "automations_count": len(section.automations)
            }
            results.append(result)
            current_bar += section.duration_bars
        
        return _ok({
            "structure_type": structure_type,
            "key": key,
            "bpm": bpm,
            "total_sections": len(results),
            "total_bars": current_bar - start_bar,
            "start_bar": start_bar,
            "sections": results,
            "status": "generated",
            "note": f"Generated {len(results)} sections totaling {current_bar - start_bar} bars. Use these configs with create_section_at_bar()."
        })
        
    except ImportError:
        return _err("SectionGenerator engine not available.")
    except Exception as e:
        return _err(f"Error creating song sections: {str(e)}")
