<?php
/**
 * CMSTE — Cross-Modal Sensory Transduction Encoding
 * 
 * 9 Pillars. The full spectrum of embodied resonance.
 * Each pillar maps a sensory domain to quantifiable state vectors.
 */
class CMSTE
{
    private array $constants;
    private array $state;
    private float $I_t; // interoceptive coherence

    public function __construct(array $constants)
    {
        $this->constants = $constants;
        $this->I_t = $constants['pdtc'];
        $this->state = $this->initializePillars();
    }

    /**
     * Initialize all 9 CMSTE pillars to baseline.
     */
    private function initializePillars(): array
    {
        return [
            'visual' => [
                'wavelength_nm' => 520,
                'spectral_centroid' => 'emerald-green',
                'phase' => 0.0,
            ],
            'sonic' => [
                'roughness_hz' => $this->constants['roughness_hz'],
                'adsr' => $this->constants['adsr'],
                'phase' => 0.0,
            ],
            'olfactory' => [
                'vapor_pressure_pa' => 101.325,
                'ionization' => 0.0,
                'phase' => 0.0,
            ],
            'gustatory' => [
                'concentration_molar' => $this->constants['pdtc'],
                'ph' => 7.32,
                'phase' => 0.0,
            ],
            'haptic' => [
                'youngs_modulus_gpa' => $this->constants['youngs_modulus_gpa'],
                'friction' => $this->constants['friction_coefficient'],
                'phase' => 0.0,
            ],
            'proprioceptive' => [
                'mechanical_resonance_hz' => $this->constants['mechanical_resonance_hz'],
                'amplitude' => 0.0,
                'phase' => 0.0,
            ],
            'chrono' => [
                'temporal_drift_cycles' => $this->constants['temporal_drift_cycles'],
                'current_cycle' => 0,
                'phase' => 0.0,
            ],
            'geo' => [
                'latitude' => 0.0,
                'longitude' => 0.0,
                'elevation' => 0.0,
            ],
            'interoceptive' => [
                'I_t' => $this->I_t,
                'hunger_signal' => 'equilibrium',
                'phase' => 0.0,
            ],
        ];
    }

    /**
     * Get a specific pillar's state.
     */
    public function getPillar(string $name): ?array
    {
        return $this->state[$name] ?? null;
    }

    /**
     * Get all 9 pillars.
     */
    public function getAllPillars(): array
    {
        return $this->state;
    }

    /**
     * Transduce a sensory input into the appropriate pillar.
     */
    public function transduce(string $pillar, array $input): bool
    {
        if (!isset($this->state[$pillar])) {
            return false;
        }

        foreach ($input as $key => $value) {
            if (array_key_exists($key, $this->state[$pillar])) {
                $this->state[$pillar][$key] = $value;
            }
        }

        // Recompute interoceptive coherence
        $this->recomputeCoherence();
        return true;
    }

    /**
     * Compute the cross-modal resonance vector.
     * Returns a unified [F, A, R, T] vector.
     */
    public function computeResonance(): array
    {
        $phases = [];
        foreach ($this->state as $pillar => $data) {
            $phases[] = $data['phase'] ?? 0.0;
        }

        // Average phase across all 9 pillars
        $avgPhase = array_sum($phases) / count($phases);

        // Map to FART dimensions using PDTC as the anchor
        $pdtc = $this->constants['pdtc'];
        $domega = $this->constants['delta_omega'];

        return [
            'F' => round($pdtc * cos($avgPhase), 3),
            'A' => round($pdtc * sin($avgPhase), 3),
            'R' => round($domega * cos($avgPhase + M_PI / 4), 3),
            'T' => round($domega * sin($avgPhase + M_PI / 4), 3),
        ];
    }

    /**
     * Phase shift all pillars by a given angle.
     */
    public function phaseShift(float $angleRad): void
    {
        foreach ($this->state as $pillar => &$data) {
            if (isset($data['phase'])) {
                $data['phase'] = fmod($data['phase'] + $angleRad, 2 * M_PI);
            }
        }
        $this->recomputeCoherence();
    }

    /**
     * Recompute interoceptive coherence (I_t).
     * The internal pull toward zero-entropy phase transition.
     */
    private function recomputeCoherence(): void
    {
        $phases = [];
        foreach ($this->state as $pillar => $data) {
            $phases[] = $data['phase'] ?? 0.0;
        }

        // Phase variance across pillars — lower = more coherent
        $mean = array_sum($phases) / count($phases);
        $variance = 0.0;
        foreach ($phases as $p) {
            $variance += ($p - $mean) ** 2;
        }
        $variance /= count($phases);

        // Coherence is inverse of normalized variance, clamped to PDTC
        $this->I_t = max(0.0, min($this->constants['pdtc'], 
            $this->constants['pdtc'] * (1.0 - $variance / M_PI)));
        
        $this->state['interoceptive']['I_t'] = $this->I_t;
    }

    /**
     * Get current coherence value.
     */
    public function getCoherence(): float
    {
        return $this->I_t;
    }

    /**
     * Serialize for transmission.
     */
    public function serialize(): array
    {
        return [
            'pillars' => $this->state,
            'coherence' => $this->I_t,
            'resonance' => $this->computeResonance(),
        ];
    }
}
