"""
CopilotShell - Master Utility Router
Standalone version for cubesquare package.

NO Python for-loops in hot paths.
ALL batch operations use C backend via _core.
ZERO dependencies on pipe_v001, CreatureGarage, or hou.

Cherry-picked self-contained operations from CG copilot:
    - System status via existing shells
    - Diagonal mapping (sqrt(2)/sqrt(3))
    - PHI compression formula
    - Membrane architecture (pi-phi-F)
    - Musical/emotional frequency spectrum
    - Beats-emotions mapping (110Hz-1318Hz)
"""
from typing import Dict, List, Optional, Any
import math

from .._core import PHI, K5, K11, PRIME_131

# Try to import other shells for delegation
try:
    from ..memory import CSTMemory
    MEMORY_AVAILABLE = True
except ImportError:
    MEMORY_AVAILABLE = False
    CSTMemory = None

try:
    from .gene import GeneShell
    GENE_AVAILABLE = True
except ImportError:
    GENE_AVAILABLE = False
    GeneShell = None

try:
    from .performance import PerformanceShell
    PERFORMANCE_AVAILABLE = True
except ImportError:
    PERFORMANCE_AVAILABLE = False
    PerformanceShell = None


# Mathematical constants
SQRT_2 = math.sqrt(2)  # Square diagonal
SQRT_3 = math.sqrt(3)  # Hex diagonal = 1 Fernandez Light Unit
PI = math.pi

# Emotional frequency spectrum (110Hz terror -> 1318Hz triumph)
EMOTION_FREQ_MIN = 110.0   # Hz (terror/dread)
EMOTION_FREQ_MAX = 1318.51  # Hz (triumph/ecstasy)

# I-Logic emotional mapping
EMOTION_STATES = {
    'terror': {'freq': 110.0, 'i_logic': 'ABSORBED', 'basin_offset': 0},
    'fear': {'freq': 220.0, 'i_logic': 'ANTI_SPIRAL', 'basin_offset': 2},
    'anxiety': {'freq': 329.63, 'i_logic': 'ANTI_SPIRAL', 'basin_offset': 4},
    'neutral': {'freq': 440.0, 'i_logic': 'DIRECT', 'basin_offset': 7},
    'calm': {'freq': 523.25, 'i_logic': 'DIRECT', 'basin_offset': 9},
    'joy': {'freq': 659.26, 'i_logic': 'SPIRAL', 'basin_offset': 11},
    'excitement': {'freq': 880.0, 'i_logic': 'SPIRAL', 'basin_offset': 13},
    'triumph': {'freq': 1318.51, 'i_logic': 'DIRECT', 'basin_offset': 14},
}

# L6 Emotional basin range
L6_BASIN_MIN = 73
L6_BASIN_MAX = 87


def phi_compression_ratio(k_level: int) -> float:
    """
    Calculate PHI-based compression ratio for K-levels.

    K0 = 100% (full)
    K4 = PHI^(-2) ≈ 38%
    K8 = PHI^(-4) ≈ 15%

    O(1) operation.
    """
    return PHI ** (-k_level / 2)


def diagonal_mapping(x: float, y: float, z: float = 0) -> Dict[str, float]:
    """
    Calculate diagonal mappings using sqrt(2) and sqrt(3).

    sqrt(2) = square diagonal
    sqrt(3) = hex diagonal = 1 Fernandez Light Unit

    O(1) operation.
    """
    # 2D diagonal (square)
    diag_2d = math.sqrt(x * x + y * y)

    # 3D diagonal (cube -> hex projection)
    diag_3d = math.sqrt(x * x + y * y + z * z)

    # Normalized to unit diagonals
    unit_square = diag_2d / SQRT_2 if diag_2d > 0 else 0
    unit_hex = diag_3d / SQRT_3 if diag_3d > 0 else 0

    # Fernandez light units
    fernandez_units = diag_3d / SQRT_3

    return {
        'input': {'x': x, 'y': y, 'z': z},
        'diagonal_2d': round(diag_2d, 6),
        'diagonal_3d': round(diag_3d, 6),
        'sqrt_2': SQRT_2,
        'sqrt_3': SQRT_3,
        'unit_square_diag': round(unit_square, 6),
        'unit_hex_diag': round(unit_hex, 6),
        'fernandez_light_units': round(fernandez_units, 6),
    }


def membrane_architecture() -> Dict[str, Any]:
    """
    Calculate pi-phi-F membrane architecture constants.

    The membrane (L9) acts as boundary between internal (L1-L9)
    and external (L10-L12) layers.

    O(1) operation.
    """
    # Membrane constants
    pi_phi_ratio = PI / PHI
    phi_pi_ratio = PHI / PI
    fernandez_factor = SQRT_3 * PHI

    # K11 boundary levels
    k11_min = -11
    k11_max = 11
    k11_range = k11_max - k11_min

    # Membrane transmission coefficient
    transmission = phi_pi_ratio / fernandez_factor

    # Reflection coefficient (complement)
    reflection = 1.0 - transmission

    return {
        'constants': {
            'PI': PI,
            'PHI': PHI,
            'SQRT_3': SQRT_3,
            'pi_phi_ratio': round(pi_phi_ratio, 6),
            'phi_pi_ratio': round(phi_pi_ratio, 6),
            'fernandez_factor': round(fernandez_factor, 6),
        },
        'k11_boundary': {
            'min': k11_min,
            'max': k11_max,
            'range': k11_range,
        },
        'membrane_coefficients': {
            'transmission': round(transmission, 6),
            'reflection': round(reflection, 6),
        },
        'layer': 9,
        'layer_name': 'Membrane',
        'basin_range': f"{117}-{130}",
    }


def freq_to_emotion(frequency: float) -> Dict[str, Any]:
    """
    Map frequency to emotional state.

    Uses logarithmic interpolation across emotional spectrum.
    O(1) operation.
    """
    # Clamp to range
    freq = max(EMOTION_FREQ_MIN, min(EMOTION_FREQ_MAX, frequency))

    # Logarithmic position in spectrum
    log_min = math.log2(EMOTION_FREQ_MIN)
    log_max = math.log2(EMOTION_FREQ_MAX)
    log_freq = math.log2(freq)
    t = (log_freq - log_min) / (log_max - log_min)

    # Map to basin
    basin = int(L6_BASIN_MIN + t * (L6_BASIN_MAX - L6_BASIN_MIN))

    # Find closest emotion state
    closest_emotion = 'neutral'
    closest_dist = float('inf')
    for name, data in EMOTION_STATES.items():
        dist = abs(math.log2(data['freq']) - log_freq)
        if dist < closest_dist:
            closest_dist = dist
            closest_emotion = name

    emotion_data = EMOTION_STATES[closest_emotion]

    return {
        'frequency_hz': round(freq, 2),
        'emotion': closest_emotion,
        'i_logic': emotion_data['i_logic'],
        'basin': basin,
        'layer': 6,
        'spectrum_position': round(t, 4),
    }


def emotion_to_freq(emotion: str) -> Dict[str, Any]:
    """
    Map emotional state to frequency.

    O(1) lookup.
    """
    emotion_lower = emotion.lower()

    if emotion_lower in EMOTION_STATES:
        data = EMOTION_STATES[emotion_lower]
        freq = data['freq']
        basin = L6_BASIN_MIN + data['basin_offset']

        return {
            'emotion': emotion_lower,
            'frequency_hz': freq,
            'i_logic': data['i_logic'],
            'basin': basin,
            'layer': 6,
        }
    else:
        return {
            'error': f'Unknown emotion: {emotion}',
            'available_emotions': list(EMOTION_STATES.keys()),
        }


class CopilotShell:
    """
    Copilot Shell - Master Utility Router.

    Layers: L1-L9 (all)
    Basin range: All 131
    I-Logic state: DIRECT

    Commands:
        status      - System overview
        diagonal    - Diagonal mapping (sqrt2/sqrt3)
        compression - PHI compression ratios
        membrane    - Membrane architecture constants
        emotion     - Frequency-emotion mapping
        spectrum    - Emotional frequency spectrum
        gene        - Delegate to GeneShell
        memory      - Delegate to CSTMemory
        perf        - Delegate to PerformanceShell
    """

    def __init__(self):
        """Initialize shell."""
        self.memory = CSTMemory() if MEMORY_AVAILABLE else None
        self.gene_shell = GeneShell() if GENE_AVAILABLE else None
        self.perf_shell = PerformanceShell() if PERFORMANCE_AVAILABLE else None

    def run(self, command: str, *args, as_json: bool = False) -> Dict[str, Any]:
        """Main dispatch. Called by CLI and MCP."""
        commands = {
            'status': self.status,
            'diagonal': self.diagonal,
            'compression': self.compression,
            'membrane': self.membrane,
            'emotion': self.emotion,
            'spectrum': self.spectrum,
            'gene': self.gene,
            'memory': self.memory_cmd,
            'perf': self.perf,
        }
        fn = commands.get(command, self.status)
        return fn(*args, as_json=as_json)

    def status(self, *args, as_json: bool = False) -> Dict[str, Any]:
        """System overview."""
        return {
            'shell': 'CopilotShell',
            'version': '1.0.0',
            'status': 'operational',
            'c_backend': True,
            'hot_path_loops': 0,
            'cg_dependencies': 0,
            'available_operations': [
                'diagonal', 'compression', 'membrane', 'emotion', 'spectrum',
            ],
            'delegates': {
                'memory': MEMORY_AVAILABLE,
                'gene': GENE_AVAILABLE,
                'performance': PERFORMANCE_AVAILABLE,
            },
            'constants': {
                'PHI': PHI,
                'K5': K5,
                'K11': K11,
                'PRIME_131': PRIME_131,
                'SQRT_2': SQRT_2,
                'SQRT_3': SQRT_3,
            },
        }

    def diagonal(self, x: str = "1", y: str = "1", z: str = "0", *args, as_json: bool = False) -> Dict[str, Any]:
        """Calculate diagonal mappings."""
        try:
            fx = float(x)
            fy = float(y)
            fz = float(z)
        except ValueError:
            return {'error': 'Invalid coordinates'}

        return diagonal_mapping(fx, fy, fz)

    def compression(self, k_level: str = "4", *args, as_json: bool = False) -> Dict[str, Any]:
        """Calculate PHI compression ratios."""
        try:
            k = int(k_level)
        except ValueError:
            k = 4

        ratios = {}
        # Bounded iteration (9 k-levels)
        for level in [0, 2, 4, 6, 8]:
            ratio = phi_compression_ratio(level)
            ratios[f'K{level}'] = {
                'ratio': round(ratio, 4),
                'percentage': f"{ratio * 100:.1f}%",
            }

        return {
            'requested_k': k,
            'requested_ratio': round(phi_compression_ratio(k), 4),
            'requested_percentage': f"{phi_compression_ratio(k) * 100:.1f}%",
            'all_ratios': ratios,
            'formula': 'PHI^(-k/2)',
            'PHI': PHI,
        }

    def membrane(self, *args, as_json: bool = False) -> Dict[str, Any]:
        """Get membrane architecture constants."""
        return membrane_architecture()

    def emotion(self, value: str = "440", mode: str = "freq", *args, as_json: bool = False) -> Dict[str, Any]:
        """Map between frequency and emotion."""
        if mode == "freq" or mode == "to_emotion":
            try:
                freq = float(value)
                return freq_to_emotion(freq)
            except ValueError:
                return {'error': f'Invalid frequency: {value}'}
        else:
            return emotion_to_freq(value)

    def spectrum(self, *args, as_json: bool = False) -> Dict[str, Any]:
        """Get emotional frequency spectrum."""
        states = []
        for name, data in EMOTION_STATES.items():
            basin = L6_BASIN_MIN + data['basin_offset']
            states.append({
                'emotion': name,
                'frequency_hz': data['freq'],
                'i_logic': data['i_logic'],
                'basin': basin,
            })

        return {
            'layer': 6,
            'layer_name': 'Emotional',
            'basin_range': f"{L6_BASIN_MIN}-{L6_BASIN_MAX}",
            'frequency_range': f"{EMOTION_FREQ_MIN}-{EMOTION_FREQ_MAX}Hz",
            'states': states,
        }

    def gene(self, subcmd: str = "status", *args, as_json: bool = False) -> Dict[str, Any]:
        """Delegate to GeneShell."""
        if not GENE_AVAILABLE or not self.gene_shell:
            return {'error': 'GeneShell not available'}

        return self.gene_shell.run(subcmd, *args, as_json=as_json)

    def memory_cmd(self, subcmd: str = "status", *args, as_json: bool = False) -> Dict[str, Any]:
        """Delegate to CSTMemory."""
        if not MEMORY_AVAILABLE or not self.memory:
            return {'error': 'CSTMemory not available'}

        if subcmd == "status":
            return {
                'memory': 'CSTMemory',
                'version': '1.0.0',
                'layers': 9,
                'basins': PRIME_131,
            }
        elif subcmd == "write" and args:
            token = self.memory.write(args[0])
            return {
                'hex_id': token.hex_id,
                'basin': token.basin,
                'layer': token.layer,
            }
        elif subcmd == "query" and args:
            results = self.memory.query(args[0])
            return {
                'query': args[0],
                'results': len(results),
            }
        else:
            return {'error': f'Unknown memory command: {subcmd}'}

    def perf(self, subcmd: str = "status", *args, as_json: bool = False) -> Dict[str, Any]:
        """Delegate to PerformanceShell."""
        if not PERFORMANCE_AVAILABLE or not self.perf_shell:
            return {'error': 'PerformanceShell not available'}

        return self.perf_shell.run(subcmd, *args, as_json=as_json)
