<?php

namespace App\Services\Prediction\Signals;

abstract class AbstractSignal implements Signal
{
    /** @return array{score: 0.0, confidence: 0.0, direction: 'stable', detail: string, data_points: 0, enabled: false} */
    protected function disabledSignal(string $detail): array
    {
        return [
            'score' => 0.0,
            'confidence' => 0.0,
            'direction' => 'stable',
            'detail' => $detail,
            'data_points' => 0,
            'enabled' => false,
        ];
    }

    /**
     * Least-squares linear regression. x = array index, y = value.
     *
     * @param  float[]  $values
     * @return array{slope: float, r_squared: float}
     */
    protected function linearRegression(array $values): array
    {
        $n = count($values);

        if ($n < 2) {
            return ['slope' => 0.0, 'r_squared' => 0.0];
        }

        $xMean = ($n - 1) / 2.0;
        $yMean = array_sum($values) / $n;

        $numerator = 0.0;
        $denominator = 0.0;

        foreach ($values as $i => $y) {
            $x = $i - $xMean;
            $numerator += $x * ($y - $yMean);
            $denominator += $x * $x;
        }

        $slope = $denominator > 0.0 ? $numerator / $denominator : 0.0;

        $ssRes = 0.0;
        $ssTot = 0.0;

        foreach ($values as $i => $y) {
            $predicted = $yMean + $slope * ($i - $xMean);
            $ssRes += ($y - $predicted) ** 2;
            $ssTot += ($y - $yMean) ** 2;
        }

        $rSquared = $ssTot > 0.0 ? max(0.0, 1.0 - ($ssRes / $ssTot)) : 0.0;

        return ['slope' => $slope, 'r_squared' => $rSquared];
    }
}
