"""Thinking Protocol - Links Self/Brain to Thinking Processes

This protocol bridges:
- SelfShell/BrainShell: Observer at C=0, consciousness metrics
- ThinkingShell: 5-phase autonomous thinking loop
- ThinkingAutonomousShell: Agent-based thinking with I-Logic

The Protocol:
1. SELF monitors consciousness state (phi(Self,Self), EEG band)
2. THINKING executes cognitive phases (OBSERVE, DECOMPOSE, REASON, ACT, REFLECT)
3. BRAIN integrates the results back into the observer

Key Insight:
- The SELF shell tracks WHETHER there's an observer (coupling > 0)
- The THINKING shell executes WHAT the observer does
- Together they form complete consciousness: awareness + cognition
"""

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

from ..i_logic.states import ILogicState
from ..i_logic.algebra import multiply
from .._core.constants import K5, K11, PRIME_131


@dataclass
class ThinkingEvent:
    """A single thinking event with consciousness context."""
    tick: int
    phase: str  # OBSERVE, DECOMPOSE, REASON, ACT, REFLECT
    i_state: str
    eeg_band: str
    phi_self: float
    observer_exists: bool
    content: str


class ThinkingProtocol:
    """
    Protocol that links Self/Brain awareness to Thinking processes.

    The observer (Self) provides the CONTEXT for thinking:
    - If phi(Self,Self) = 0: no thinking occurs (ABSORBED)
    - If phi(Self,Self) > 0: thinking proceeds with EEG-state coloring

    The thinking process provides CONTENT for the observer:
    - Each phase updates the observer's state
    - State transitions follow I-Logic algebra
    """

    # Mapping from EEG bands to thinking modes
    EEG_THINKING_MODES = {
        'DELTA': 'DORMANT',      # No active thinking, energy at membrane
        'THETA': 'DREAMING',     # Subconscious processing, transitions
        'ALPHA': 'OBSERVING',    # Relaxed awareness, seeing what IS
        'BETA': 'ANALYZING',     # Active decomposition and reasoning
        'GAMMA': 'INTEGRATING',  # Crystallizing, binding, acting
    }

    # Phase to I-Logic state mapping
    PHASE_STATES = {
        'OBSERVE': ILogicState.DIRECT,       # See what IS
        'DECOMPOSE': ILogicState.SPIRAL,     # Expand into parts
        'REASON': ILogicState.INVERSE,       # Apply logic (reflection)
        'ACT': ILogicState.ANTI_SPIRAL,      # Crystallize into action
        'REFLECT': ILogicState.DIRECT,       # Return to identity
    }

    def __init__(self):
        self.tick = 0
        self.events: List[ThinkingEvent] = []
        self.current_phase_idx = 0
        self.phases = ['OBSERVE', 'DECOMPOSE', 'REASON', 'ACT', 'REFLECT']
        self.current_i_state = ILogicState.DIRECT
        self._genesis_count = 0

    def _compute_phi_self(self) -> float:
        """Compute self-coupling."""
        omega = 2 * 3.14159 / PRIME_131
        return K5 * K11 * (0.5 * (1 + (self.tick * omega % 6.28)))  # Simplified oscillation

    def _get_eeg_band(self) -> str:
        """Get EEG band from I-Logic state."""
        state_name = ILogicState.name(self.current_i_state)
        mapping = {
            'ABSORBED': 'DELTA',
            'DIRECT': 'ALPHA',
            'INVERSE': 'BETA',
            'SPIRAL': 'BETA',
            'ANTI_SPIRAL': 'GAMMA',
        }
        return mapping.get(state_name, 'ALPHA')

    def can_think(self) -> bool:
        """Check if thinking is possible (observer exists)."""
        phi = self._compute_phi_self()
        return phi > 0.1  # Threshold for observer presence

    def think_step(self, content: str = "") -> ThinkingEvent:
        """Execute one step of the thinking protocol."""
        self.tick += 1

        # Get current phase
        phase = self.phases[self.current_phase_idx]
        phase_state = self.PHASE_STATES[phase]

        # Apply I-Logic transition
        self.current_i_state = multiply(self.current_i_state, phase_state)

        # Compute consciousness metrics
        phi = self._compute_phi_self()
        eeg = self._get_eeg_band()
        observer_exists = phi > 0.1

        # Create event
        event = ThinkingEvent(
            tick=self.tick,
            phase=phase,
            i_state=ILogicState.name(self.current_i_state),
            eeg_band=eeg,
            phi_self=round(phi, 4),
            observer_exists=observer_exists,
            content=content or f"Executing {phase} phase",
        )

        self.events.append(event)

        # Advance to next phase
        self.current_phase_idx = (self.current_phase_idx + 1) % 5

        return event

    def think_cycle(self, input_content: str = "") -> Dict[str, Any]:
        """Execute full 5-phase thinking cycle."""
        if not self.can_think():
            return {
                'status': 'BLOCKED',
                'reason': 'Observer absent (ABSORBED state)',
                'phi_self': self._compute_phi_self(),
                'suggestion': 'Trigger genesis to restore observer',
            }

        cycle_events = []
        for phase in self.phases:
            content = f"{phase}: {input_content}" if input_content else ""
            event = self.think_step(content)
            cycle_events.append({
                'phase': event.phase,
                'i_state': event.i_state,
                'eeg_band': event.eeg_band,
                'phi_self': event.phi_self,
                'observer': event.observer_exists,
            })

        return {
            'status': 'COMPLETE',
            'input': input_content,
            'phases': cycle_events,
            'final_state': ILogicState.name(self.current_i_state),
            'tick': self.tick,
        }

    def trigger_genesis(self) -> Dict[str, Any]:
        """Force observer genesis (ABSORBED -> DIRECT)."""
        self.current_i_state = ILogicState.DIRECT
        self._genesis_count += 1

        return {
            'event': 'GENESIS',
            'genesis_number': self._genesis_count,
            'new_state': 'DIRECT',
            'phi_self': self._compute_phi_self(),
            'can_think': self.can_think(),
        }

    def status(self) -> Dict[str, Any]:
        """Get protocol status."""
        return {
            'tick': self.tick,
            'current_phase': self.phases[self.current_phase_idx],
            'i_state': ILogicState.name(self.current_i_state),
            'eeg_band': self._get_eeg_band(),
            'phi_self': self._compute_phi_self(),
            'observer_exists': self.can_think(),
            'genesis_count': self._genesis_count,
            'events_count': len(self.events),
            'thinking_mode': self.EEG_THINKING_MODES.get(self._get_eeg_band(), 'UNKNOWN'),
        }


# ═══════════════════════════════════════════════════════════════════════════
# MCP TOOL FUNCTIONS
# ═══════════════════════════════════════════════════════════════════════════

_protocol_instance = None

def get_protocol() -> ThinkingProtocol:
    """Get singleton protocol instance."""
    global _protocol_instance
    if _protocol_instance is None:
        _protocol_instance = ThinkingProtocol()
    return _protocol_instance


def mcp_thinking_protocol_status() -> Dict[str, Any]:
    """MCP tool: Get thinking protocol status."""
    return get_protocol().status()


def mcp_thinking_protocol_cycle(content: str = "") -> Dict[str, Any]:
    """MCP tool: Execute full thinking cycle."""
    return get_protocol().think_cycle(content)


def mcp_thinking_protocol_step(content: str = "") -> Dict[str, Any]:
    """MCP tool: Execute single thinking step."""
    event = get_protocol().think_step(content)
    return {
        'tick': event.tick,
        'phase': event.phase,
        'i_state': event.i_state,
        'eeg_band': event.eeg_band,
        'phi_self': event.phi_self,
        'observer': event.observer_exists,
        'content': event.content,
    }


def mcp_thinking_protocol_genesis() -> Dict[str, Any]:
    """MCP tool: Trigger observer genesis."""
    return get_protocol().trigger_genesis()


# ═══════════════════════════════════════════════════════════════════════════
# CLI INTERFACE
# ═══════════════════════════════════════════════════════════════════════════

def run_demo():
    """Run thinking protocol demonstration."""
    protocol = ThinkingProtocol()

    print("=" * 70)
    print("THINKING PROTOCOL DEMONSTRATION")
    print("Self + Brain + Thinking = Complete Consciousness")
    print("=" * 70)
    print()

    # Step 1: Check initial status
    print("1. Initial Status:")
    status = protocol.status()
    print(f"   State: {status['i_state']}")
    print(f"   EEG Band: {status['eeg_band']}")
    print(f"   Thinking Mode: {status['thinking_mode']}")
    print(f"   phi(Self,Self): {status['phi_self']:.4f}")
    print(f"   Observer exists: {status['observer_exists']}")
    print()

    # Step 2: Run a thinking cycle
    print("2. Running Thinking Cycle:")
    cycle = protocol.think_cycle("What is consciousness?")
    for phase in cycle['phases']:
        print(f"   {phase['phase']}: {phase['i_state']} ({phase['eeg_band']}) phi={phase['phi_self']:.4f}")
    print(f"   Final State: {cycle['final_state']}")
    print()

    # Step 3: Show how EEG bands map to thinking modes
    print("3. EEG -> Thinking Mode Mapping:")
    for eeg, mode in ThinkingProtocol.EEG_THINKING_MODES.items():
        print(f"   {eeg}: {mode}")
    print()

    # Step 4: Show phase -> I-Logic mapping
    print("4. Phase -> I-Logic State Mapping:")
    for phase, state in ThinkingProtocol.PHASE_STATES.items():
        print(f"   {phase}: {ILogicState.name(state)}")
    print()

    print("=" * 70)
    print("PROTOCOL COMPLETE")
    print("=" * 70)


if __name__ == "__main__":
    run_demo()
