"""
Primitives Shell - Verified O(1) Primitives
Standalone version for cubesquare package.
"""

import json
import time
from typing import Dict, Any
from .._core import PHI, K5, K11, PRIME_131
from ..circular.srl_integration import srl_distance, srl_morton_encode
from ..circular.state_machine import ILogicStateMachine, ILogicState


class PrimitivesShell:
    """
    Primitives Shell.

    Provides verified O(1) primitive operations:
    - Morton encoding/decoding
    - Basin computation
    - SRL computation
    - I-Logic multiplication
    """

    def __init__(self):
        """Initialize Primitives shell."""
        self.state_machine = ILogicStateMachine()

    def status(self, as_json: bool = False) -> Dict[str, Any]:
        """Get Primitives system status."""
        result = {
            'system': 'Primitives Shell',
            'version': '1.0.0',
            'primitives': {
                'morton': {'complexity': 'O(1)', 'ops': '21 bit operations', 'verified': True},
                'basin': {'complexity': 'O(1)', 'ops': '8 operations', 'verified': True},
                'srl': {'complexity': 'O(1)', 'ops': '<=25 iterations', 'verified': True},
                'i_logic': {'complexity': 'O(1) per multiplication', 'ops': 'N multiplications', 'verified': True},
            },
            'status': 'operational',
        }

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

    def morton_encode(self, x: int, y: int, z: int, as_json: bool = False) -> Dict[str, Any]:
        """Encode 3D coordinates to Morton code."""
        start = time.perf_counter()
        morton = srl_morton_encode(x, y, z)
        elapsed_ns = (time.perf_counter() - start) * 1e9

        result = {
            'coords': (x, y, z),
            'morton_code': morton,
            'morton_hex': hex(morton),
            'time_ns': elapsed_ns,
            'complexity': 'O(1)',
        }

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

    def basin(self, hex_id: str, as_json: bool = False) -> Dict[str, Any]:
        """Compute basin from hex ID."""
        start = time.perf_counter()

        # Parse hex to int
        try:
            hex_val = int(hex_id, 16) if hex_id.startswith('0x') or hex_id.isalnum() else hash(hex_id)
        except ValueError:
            hex_val = hash(hex_id)

        basin = hex_val % PRIME_131
        elapsed_ns = (time.perf_counter() - start) * 1e9

        # Determine layer
        layer = None
        for i in range(9):
            start_basin = i * 15 if i < 8 else i * 14 + 3
            end_basin = (i + 1) * 15 if i < 8 else 131
            if start_basin <= basin < end_basin:
                layer = f'L{i + 1}'
                break

        result = {
            'hex_id': hex_id,
            'basin': basin,
            'layer': layer,
            'formula': 'hex % 131',
            'time_ns': elapsed_ns,
            'complexity': 'O(1)',
        }

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

    def srl(self, distance: int, as_json: bool = False) -> Dict[str, Any]:
        """Compute SRL distance."""
        start = time.perf_counter()
        t = srl_distance(distance)
        elapsed_ns = (time.perf_counter() - start) * 1e9

        result = {
            'distance': distance,
            'srl_time': t,
            'formula': 't = sqrt(d)',
            'verification': f'{t}^2 = {t*t} (d={distance}, residual={distance - t*t})',
            'time_ns': elapsed_ns,
            'complexity': 'O(1)',
        }

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

    def i_logic(self, state1: str, state2: str, as_json: bool = False) -> Dict[str, Any]:
        """Multiply two I-Logic states."""
        states = {
            'DIRECT': ILogicState.DIRECT,
            'INVERSE': ILogicState.INVERSE,
            'SPIRAL': ILogicState.SPIRAL,
            'ANTI_SPIRAL': ILogicState.ANTI_SPIRAL,
            'ABSORBED': ILogicState.ABSORBED,
        }

        state1 = state1.upper()
        state2 = state2.upper()

        if state1 not in states or state2 not in states:
            return {'error': f'Unknown state. Available: {list(states.keys())}'}

        start = time.perf_counter()
        result_state = self.state_machine.multiply(states[state1], states[state2])
        elapsed_ns = (time.perf_counter() - start) * 1e9

        result = {
            'state1': state1,
            'state2': state2,
            'result': result_state.name,
            'formula': f'{state1} x {state2} = {result_state.name}',
            'is_stable': result_state.is_stable(),
            'time_ns': elapsed_ns,
            'complexity': 'O(1)',
        }

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

    def use(self, as_json: bool = False) -> Dict[str, Any]:
        """Show when to use each primitive."""
        result = {
            'morton': {
                'use_when': 'Need spatial locality for 3D coordinates',
                'example': 'primitives morton 10 20 30',
            },
            'basin': {
                'use_when': 'Need semantic clustering for token',
                'example': 'primitives basin 2A9E0100',
            },
            'srl': {
                'use_when': 'Need time from distance (t=sqrt(d))',
                'example': 'primitives srl 1000000',
            },
            'i_logic': {
                'use_when': 'Need state multiplication for routing',
                'example': 'primitives i_logic SPIRAL INVERSE',
            },
        }

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

    def why(self, as_json: bool = False) -> Dict[str, Any]:
        """Explain why O(1) primitives matter."""
        result = {
            'key_insight': 'Cost determined at algorithm design time, not query time',
            'benefits': [
                'Predictable performance regardless of data size',
                'No search required - compute directly',
                'Can pre-compute routing outcomes',
                'Enables semantic memory at scale',
            ],
            'distinction': {
                'traditional': 'Execute path, observe outcome (N network calls)',
                'cst': 'Compute path, know outcome (N-1 multiplications)',
            },
        }

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

    def run(self, command: str, *args, as_json: bool = False) -> Any:
        """Run a Primitives shell command."""
        commands = {
            'status': lambda: self.status(as_json),
            'morton': lambda: self.morton_encode(int(args[0]), int(args[1]), int(args[2]), as_json) if len(args) >= 3 else {'error': 'Three coordinates required (x y z)'},
            'basin': lambda: self.basin(args[0], as_json) if args else {'error': 'Hex ID required'},
            'srl': lambda: self.srl(int(args[0]), as_json) if args else {'error': 'Distance required'},
            'i_logic': lambda: self.i_logic(args[0], args[1], as_json) if len(args) >= 2 else {'error': 'Two states required'},
            'use': lambda: self.use(as_json),
            'why': lambda: self.why(as_json),
        }

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