<?php

namespace App\Services\Forecasting\Features;

use App\Services\Forecasting\Contracts\ForecastFeature;
use App\Services\Forecasting\WeeklyPumpPriceLoader;
use Carbon\CarbonInterface;

/**
 * Mean-reversion term: gap between the most recent observable ULSP
 * (target − 7d) and its 8-week trailing mean (target − 7d through
 * target − 56d, inclusive).
 *
 * Empirically this is the single most useful 1-week-ahead feature for
 * UK pump prices — pump retailers tend to revert to their recent
 * trailing mean, especially after sudden moves.
 */
final class UlspMinusMa8 implements ForecastFeature
{
    private const int WINDOW_WEEKS = 8;

    public function __construct(
        private readonly WeeklyPumpPriceLoader $loader,
    ) {}

    public function name(): string
    {
        return 'ulsp_minus_ma8';
    }

    public function valueFor(CarbonInterface $targetMonday): ?float
    {
        $values = [];
        foreach ($this->sourceDates($targetMonday) as $d) {
            $v = $this->loader->ulspPence($d->toDateString());
            if ($v === null) {
                return null;
            }
            $values[] = (float) $v;
        }

        $latest = $values[0];
        $mean = array_sum($values) / count($values);

        return $latest - $mean;
    }

    public function sourceDates(CarbonInterface $targetMonday): array
    {
        $dates = [];
        for ($w = 1; $w <= self::WINDOW_WEEKS; $w++) {
            $dates[] = $targetMonday->copy()->subDays(7 * $w);
        }

        return $dates;
    }
}
