<?php

namespace App\Services\Forecasting\Features;

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

/**
 * Cyclic week-of-year encoding. Two instances expected, one for sin and
 * one for cos. Together they let the linear model fit a smooth annual
 * seasonal cycle without a 52-way one-hot expansion.
 *
 * This is a pure calendar feature — no DB read. sourceDates is empty,
 * so the LeakDetector has nothing to validate against.
 */
final class WeekOfYearTrig implements ForecastFeature
{
    public function __construct(public readonly string $component)
    {
        if (! in_array($component, ['sin', 'cos'], true)) {
            throw new InvalidArgumentException('component must be "sin" or "cos"');
        }
    }

    public function name(): string
    {
        return 'week_of_year_'.$this->component;
    }

    public function valueFor(CarbonInterface $targetMonday): ?float
    {
        $week = (int) $targetMonday->format('W'); // ISO week number 1..53
        $angle = 2.0 * M_PI * $week / 52.0;

        return $this->component === 'sin' ? sin($angle) : cos($angle);
    }

    public function sourceDates(CarbonInterface $targetMonday): array
    {
        return [];
    }
}
