<?php
/**
 * PHASE STATE — The Thermal Chromatic Engine
 * 
 * Solid  = What HOLDS (Brown)
 * Liquid = What BREAKS (Blue)  
 * Gas    = What's MISSING (Green)
 * Plasma = What EMERGES (Yellow)
 * Burn   = RED ZONE (Cache purge)
 * 
 * States flow: Brown → Blue → Green → Yellow → [Red if breach]
 */
class PhaseState
{
    private string $current;
    private string $previous;
    private float $energy;
    private float $pdct;
    private float $delta_omega;
    private float $tau;
    private array $sequence;
    private array $history;
    private int $cycleCount;

    // FART signatures per state
    private array $fart_signatures;

    public function __construct(array $constants)
    {
        $this->current = 'brown';
        $this->previous = 'brown';
        $this->energy = $constants['pdtc'];
        $this->pdct = $constants['pdtc'];
        $this->delta_omega = $constants['delta_omega'];
        $this->tau = $constants['tau'];
        $this->sequence = $constants['phase_sequence'];
        $this->history = [];
        $this->cycleCount = 0;

        $this->fart_signatures = [
            'brown' => $constants['fart_solid'],
            'blue'  => $constants['fart_liquid'],
            'green' => $constants['fart_gas'],
        ];
    }

    /**
     * Get current thermal state name.
     */
    public function getCurrentState(): string
    {
        return $this->current;
    }

    /**
     * Map thermal color to phase name.
     */
    public function getPhaseName(): string
    {
        $map = [
            'brown' => 'solid',
            'blue'  => 'liquid',
            'green' => 'gas',
            'yellow' => 'plasma',
            'red'   => 'burn',
        ];
        return $map[$this->current] ?? 'unknown';
    }

    /**
     * Transition to the next phase in sequence.
     * Returns the new state, or 'red' if energy exceeds burn threshold.
     */
    public function transition(float $inputEnergy): string
    {
        // Check for RED ZONE
        if ($inputEnergy > $this->pdct + $this->delta_omega) {
            $this->previous = $this->current;
            $this->current = 'red';
            $this->recordHistory('burn', $inputEnergy);
            return 'red';
        }

        // Advance in the sequence
        $currentIndex = array_search($this->current, $this->sequence);
        if ($currentIndex === false) {
            $currentIndex = 0;
        }

        $nextIndex = ($currentIndex + 1) % count($this->sequence);
        $this->previous = $this->current;
        $this->current = $this->sequence[$nextIndex];

        // Energy transfer using tau decay
        $this->energy = $inputEnergy * $this->tau;
        $this->cycleCount++;

        $this->recordHistory($this->current, $this->energy);
        return $this->current;
    }

    /**
     * Force transition to a specific state (for external phase alignment).
     */
    public function forceState(string $color): bool
    {
        if (!in_array($color, $this->sequence)) {
            return false;
        }
        $this->previous = $this->current;
        $this->current = $color;
        $this->recordHistory($color, $this->energy);
        return true;
    }

    /**
     * Get the FART signature for the current state.
     */
    public function getFART(): array
    {
        return $this->fart_signatures[$this->current] ?? [
            'F' => [0.333, 0.333, 0.334],
            'A' => [0.333, 0.334, 0.333],
            'R' => [0.334, 0.333, 0.333],
            'T' => [0.333, 0.333, 0.334],
        ];
    }

    /**
     * Get the MA gap count for the current transition.
     */
    public function getMAGap(): int
    {
        $gaps = [
            'brown' => 0,
            'blue'  => $this->sequence ? 1 : 0,  // solid_to_liquid: 1 Ma
            'green' => 3,                          // liquid_to_gas: 3 Ma
            'yellow' => 5,                        // gas_to_solid: 5 Ma
            'red' => 0,
        ];
        return $gaps[$this->current] ?? 0;
    }

    /**
     * Compute energy conservation across the phase transition.
     * The ADSR Hamiltonian: zero energy loss during shifting.
     */
    public function computeHamiltonian(float $attack, float $decay, float $sustain, float $release): float
    {
        // H = A*D*S*R * energy
        $adsr_product = $attack * $decay * $sustain * $release;
        return $adsr_product * $this->energy;
    }

    /**
     * Check if the system is in thermal equilibrium.
     */
    public function isEquilibrium(): bool
    {
        return abs($this->energy - $this->pdct) < $this->delta_omega;
    }

    /**
     * Check if we're in burn (red zone).
     */
    public function isBurning(): bool
    {
        return $this->current === 'red';
    }

    /**
     * Purge the cache — only possible from burn state.
     * Returns true if successful.
     */
    public function purgeCache(): bool
    {
        if (!$this->isBurning()) {
            return false;
        }

        $this->history = [];
        $this->cycleCount = 0;
        $this->current = 'brown'; // Reset to solid baseline
        $this->energy = $this->pdct;
        return true;
    }

    /**
     * Record state transition in history.
     */
    private function recordHistory(string $state, float $energy): void
    {
        $this->history[] = [
            'timestamp' => microtime(true),
            'state' => $state,
            'phase' => $this->getPhaseName(),
            'energy' => round($energy, 6),
            'cycle' => $this->cycleCount,
        ];

        // Keep last 72 cycles (temporal_drift_cycles)
        if (count($this->history) > 72) {
            array_shift($this->history);
        }
    }

    /**
     * Serialize current phase state.
     */
    public function serialize(): array
    {
        return [
            'current_color' => $this->current,
            'phase_name' => $this->getPhaseName(),
            'previous' => $this->previous,
            'energy' => round($this->energy, 6),
            'ma_gap' => $this->getMAGap(),
            'fart' => $this->getFART(),
            'is_equilibrium' => $this->isEquilibrium(),
            'is_burning' => $this->isBurning(),
            'cycle_count' => $this->cycleCount,
            'history_depth' => count($this->history),
        ];
    }
}
