"""Constants for the rule-based blendshape compiler.

References:
- docs/research/vad-to-arkit-blendshape-mapping.md §4, §5, §6
- data/emotion/emotion_vad_anchors.json (v1.5, [-1,1] scale)
- examples/vanilla-basic/index.html:207-258 (52 ARKit ordering)
"""
ARKIT_52_NAMES = [
    "browDownLeft", "browDownRight", "browInnerUp",
    "browOuterUpLeft", "browOuterUpRight",
    "cheekPuff", "cheekSquintLeft", "cheekSquintRight",
    "eyeBlinkLeft", "eyeBlinkRight",
    "eyeLookDownLeft", "eyeLookDownRight",
    "eyeLookInLeft", "eyeLookInRight",
    "eyeLookOutLeft", "eyeLookOutRight",
    "eyeLookUpLeft", "eyeLookUpRight",
    "eyeSquintLeft", "eyeSquintRight",
    "eyeWideLeft", "eyeWideRight",
    "jawForward", "jawLeft", "jawOpen", "jawRight",
    "mouthClose",
    "mouthDimpleLeft", "mouthDimpleRight",
    "mouthFrownLeft", "mouthFrownRight",
    "mouthFunnel",
    "mouthLeft",
    "mouthLowerDownLeft", "mouthLowerDownRight",
    "mouthPressLeft", "mouthPressRight",
    "mouthPucker",
    "mouthRight",
    "mouthRollLower", "mouthRollUpper",
    "mouthShrugLower", "mouthShrugUpper",
    "mouthSmileLeft", "mouthSmileRight",
    "mouthStretchLeft", "mouthStretchRight",
    "mouthUpperUpLeft", "mouthUpperUpRight",
    "noseSneerLeft", "noseSneerRight",
    "tongueOut",
]
assert len(ARKIT_52_NAMES) == 52

NAME_TO_IDX = {name: i for i, name in enumerate(ARKIT_52_NAMES)}

# Channel categories (V3 decision §2.4)
LIPSYNC_ONLY = [22, 23, 25, 26, 31, 32, 33, 34, 37, 38, 39, 40, 45, 46, 47, 48, 51]
EXPRESSION_ONLY = [0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
SHARED_CHANNELS = [5, 24, 27, 28, 29, 30, 35, 36, 41, 42, 43, 44, 49, 50]

_all_channels = set(LIPSYNC_ONLY) | set(EXPRESSION_ONLY) | set(SHARED_CHANNELS)
assert _all_channels == set(range(52))
assert len(LIPSYNC_ONLY) + len(EXPRESSION_ONLY) + len(SHARED_CHANNELS) == 52

ACTIVE_CHANNELS = sorted(set(EXPRESSION_ONLY) | set(SHARED_CHANNELS))
assert len(ACTIVE_CHANNELS) == 35

# Gamma per channel category
GAMMA_MOUTH_SMILE_FROWN = 1.8
GAMMA_EYE = 1.3
GAMMA_BROW = 1.5
GAMMA_NOSE = 2.0

# RBF parameters (on [-1,1] scale)
RBF_SIGMA = 0.60
RBF_EMOTION_FAMILY_BOOST = 2.0
RBF_NEUTRAL_DEEMPHASIS = 0.5

# Dynamic blend weights
BLEND_NEUTRAL_THRESHOLD = 0.20
BLEND_NEUTRAL_WEIGHT = 0.75
BLEND_EXTREME_THRESHOLD = 0.80
BLEND_EXTREME_WEIGHT = 0.40
BLEND_DEFAULT_WEIGHT = 0.60

# SHARED channel LAM weights (runtime merge; not used in compiler itself)
LAM_WEIGHTS_SHARED = {
    5: 0.70, 24: 0.90, 27: 0.40, 28: 0.40, 29: 0.50, 30: 0.50,
    35: 0.70, 36: 0.70, 41: 0.55, 42: 0.45,
    43: 0.50, 44: 0.50, 49: 0.35, 50: 0.35,
}

# Conflict resolution thresholds (§5.4, on [-1,1] scale)
VALENCE_EXCLUSION_THRESHOLD = 0.10
DOMINANCE_BROW_CONFLICT_HIGH = 0.30
DOMINANCE_BROW_CONFLICT_LOW = -0.30
AROUSAL_VISIBILITY_GATE = -0.70
AROUSAL_EXTREME_AMP_THRESHOLD = 0.70
AROUSAL_EXTREME_AMP_COEFF = 0.60
