"""I-Logic States

5 states implemented as complex numbers for natural multiplication.
"""
from __future__ import annotations

from typing import Optional


class ILogicState:
    """I-Logic state with complex number representation."""

    # States as complex numbers
    DIRECT = 1 + 0j       # 1
    INVERSE = -1 + 0j     # -1
    SPIRAL = 0 + 1j       # +i
    ANTI_SPIRAL = 0 - 1j  # -i
    ABSORBED = 0 + 0j     # 0

    # Name mapping
    NAMES = {
        1 + 0j: "DIRECT",
        -1 + 0j: "INVERSE",
        0 + 1j: "SPIRAL",
        0 - 1j: "ANTI_SPIRAL",
        0 + 0j: "ABSORBED"
    }

    # Symbolic mapping
    SYMBOLS = {
        1 + 0j: "1",
        -1 + 0j: "-1",
        0 + 1j: "+i",
        0 - 1j: "-i",
        0 + 0j: "0"
    }

    ALL_STATES = [DIRECT, INVERSE, SPIRAL, ANTI_SPIRAL, ABSORBED]
    NON_ZERO_STATES = [DIRECT, INVERSE, SPIRAL, ANTI_SPIRAL]

    @staticmethod
    def name(state: complex) -> str:
        """Get name of state."""
        return ILogicState.NAMES.get(state, f"UNKNOWN({state})")

    @staticmethod
    def symbol(state: complex) -> str:
        """Get symbol of state."""
        return ILogicState.SYMBOLS.get(state, f"?({state})")

    @staticmethod
    def from_name(name: str) -> Optional[complex]:
        """Get state from name."""
        name_upper = name.upper().strip()
        for state, state_name in ILogicState.NAMES.items():
            if state_name == name_upper:
                return state
        # Also accept symbols
        symbol_map = {
            "1": ILogicState.DIRECT,
            "-1": ILogicState.INVERSE,
            "+I": ILogicState.SPIRAL,
            "I": ILogicState.SPIRAL,
            "-I": ILogicState.ANTI_SPIRAL,
            "0": ILogicState.ABSORBED
        }
        return symbol_map.get(name_upper)

    @staticmethod
    def normalize(result: complex) -> complex:
        """Normalize floating point result to exact state."""
        if abs(result) < 1e-10:
            return ILogicState.ABSORBED
        elif abs(result - 1) < 1e-10:
            return ILogicState.DIRECT
        elif abs(result + 1) < 1e-10:
            return ILogicState.INVERSE
        elif abs(result - 1j) < 1e-10:
            return ILogicState.SPIRAL
        elif abs(result + 1j) < 1e-10:
            return ILogicState.ANTI_SPIRAL
        else:
            raise ValueError(f"Invalid state: {result}")
