<?php

declare(strict_types=1);

namespace App\Services;

use DateTimeImmutable;

/**
 * Shared contract for fair year-on-year comparisons.
 *
 * If either selected year is the current calendar year, only completed months
 * before the current month are compared in both years. Two completed past
 * years continue to use January through December.
 */
final class FairYearComparisonPolicy
{
    private int $currentYear;
    private int $currentMonth;

    public function __construct(?DateTimeImmutable $today = null)
    {
        $today = $today ?? new DateTimeImmutable('today');
        $this->currentYear = (int)$today->format('Y');
        $this->currentMonth = (int)$today->format('n');
    }

    /** @return array<string, mixed> */
    public function resolve(int $year, int $compareYear): array
    {
        $includesCurrentYear = $year === $this->currentYear || $compareYear === $this->currentYear;
        $lastCompleteMonth = $includesCurrentYear ? max(0, $this->currentMonth - 1) : 12;
        $isFairCurrentYearComparison = $includesCurrentYear;

        $fromDate = null;
        $toDate = null;
        if ($isFairCurrentYearComparison && $lastCompleteMonth > 0) {
            $fromDate = sprintf('%04d-01-01', $year);
            $toDate = (new DateTimeImmutable(sprintf('%04d-%02d-01', $year, $lastCompleteMonth)))
                ->modify('last day of this month')
                ->format('Y-m-d');
        }

        return [
            'current_calendar_year' => $this->currentYear,
            'current_calendar_month' => $this->currentMonth,
            'includes_current_year' => $includesCurrentYear,
            'fair_current_year_comparison' => $isFairCurrentYearComparison,
            'last_complete_month' => $lastCompleteMonth,
            'start_month' => $lastCompleteMonth > 0 ? 1 : 0,
            'end_month' => $lastCompleteMonth,
            'from_date' => $fromDate,
            'to_date' => $toDate,
            'months_count' => $lastCompleteMonth,
            'current_month_excluded' => $includesCurrentYear ? $this->currentMonth : null,
        ];
    }

    /** @return int[] */
    public function availableYears(int $minimumYear = 2014): array
    {
        $minimumYear = min($minimumYear, $this->currentYear);
        return range($this->currentYear, $minimumYear);
    }
}
