"""
CST Shell - Core CST Operations
Standalone version for cubesquare package.
"""

import json
from typing import Dict, Any, Optional
from .._core import PHI, K5, K11, PRIME_131


class CSTShell:
    """
    CST (Coordinate Space Tokenization) Shell.

    Provides core CST operations:
    - Layer queries (L1-L9)
    - Basin operations (0-130)
    - Token management
    """

    def __init__(self):
        """Initialize CST shell."""
        self.layers = {
            'L1': {'name': 'Geometric', 'basins': range(0, 15)},
            'L2': {'name': 'Semantic', 'basins': range(15, 30)},
            'L3': {'name': 'Spatial', 'basins': range(30, 44)},
            'L4': {'name': 'Functional', 'basins': range(44, 59)},
            'L5': {'name': 'Probabilistic', 'basins': range(59, 73)},
            'L6': {'name': 'Emotional', 'basins': range(73, 88)},
            'L7': {'name': 'Frequency', 'basins': range(88, 102)},
            'L8': {'name': 'Electromagnetic', 'basins': range(102, 117)},
            'L9': {'name': 'Membrane', 'basins': range(117, 131)},
        }

    def status(self, as_json: bool = False) -> Dict[str, Any]:
        """Get CST system status."""
        result = {
            'system': 'CST Shell',
            'version': '1.0.0',
            'layers': 9,
            'basins': PRIME_131,
            'constants': {
                'PHI': PHI,
                'K5': K5,
                'K11': K11,
                'PRIME_131': PRIME_131,
            },
            'status': 'operational',
        }

        if as_json:
            return json.dumps(result, indent=2)
        return result

    def list_layers(self, as_json: bool = False) -> Dict[str, Any]:
        """List all 9 CST layers."""
        result = {
            'layers': [
                {
                    'id': f'L{i+1}',
                    'name': layer['name'],
                    'basin_range': f"{list(layer['basins'])[0]}-{list(layer['basins'])[-1]}",
                    'basin_count': len(list(layer['basins'])),
                }
                for i, (lid, layer) in enumerate(self.layers.items())
            ]
        }

        if as_json:
            return json.dumps(result, indent=2)
        return result

    def get_layer(self, layer_id: str, as_json: bool = False) -> Dict[str, Any]:
        """Get information about a specific layer."""
        layer_id = layer_id.upper()
        if layer_id not in self.layers:
            return {'error': f'Unknown layer: {layer_id}'}

        layer = self.layers[layer_id]
        basins = list(layer['basins'])

        result = {
            'layer_id': layer_id,
            'name': layer['name'],
            'basins': {
                'start': basins[0],
                'end': basins[-1],
                'count': len(basins),
            },
        }

        if as_json:
            return json.dumps(result, indent=2)
        return result

    def get_basin(self, basin_id: int, as_json: bool = False) -> Dict[str, Any]:
        """Get information about a specific basin."""
        if basin_id < 0 or basin_id >= PRIME_131:
            return {'error': f'Invalid basin: {basin_id}. Must be 0-{PRIME_131-1}'}

        # Find which layer this basin belongs to
        layer_id = None
        for lid, layer in self.layers.items():
            if basin_id in layer['basins']:
                layer_id = lid
                break

        result = {
            'basin_id': basin_id,
            'layer': layer_id,
            'layer_name': self.layers[layer_id]['name'] if layer_id else 'Unknown',
            'phase_angle': (basin_id / PRIME_131) * 360,
            'phi_ratio': basin_id / PHI if basin_id > 0 else 0,
        }

        if as_json:
            return json.dumps(result, indent=2)
        return result

    def token_to_basin(self, hex_id: str) -> int:
        """Convert token hex ID to basin number."""
        # Simple hash-based basin assignment
        hash_val = int(hex_id, 16) if hex_id.isalnum() else hash(hex_id)
        return hash_val % PRIME_131

    def run(self, command: str, *args, as_json: bool = False) -> Any:
        """Run a CST shell command."""
        commands = {
            'status': lambda: self.status(as_json),
            'list': lambda: self.list_layers(as_json),
            'layers': lambda: self.list_layers(as_json),
            'layer': lambda: self.get_layer(args[0], as_json) if args else {'error': 'Layer ID required'},
            'basin': lambda: self.get_basin(int(args[0]), as_json) if args else {'error': 'Basin ID required'},
        }

        if command in commands:
            return commands[command]()
        else:
            return {'error': f'Unknown command: {command}', 'available': list(commands.keys())}
