<?php

declare(strict_types=1);

namespace Drupal\native_observability_dashboard\Service;

use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\native_observability_dashboard\ValueObject\TimeRange;
use Symfony\Component\HttpFoundation\RequestStack;

/**
 * Resolves the selected dashboard time range from the current request.
 */
final class DashboardTimeRangeResolver {

  /**
   * Defines the default dashboard range key.
   */
  private const DEFAULT_RANGE = '30m';

  /**
   * Defines the supported dashboard ranges.
   */
  private const ALLOWED_RANGES = [
    '15m' => [
      'seconds' => 900,
      'label' => 'Last 15 minutes',
    ],
    '30m' => [
      'seconds' => 1800,
      'label' => 'Last 30 minutes',
    ],
    '1h' => [
      'seconds' => 3600,
      'label' => 'Last 1 hour',
    ],
    '6h' => [
      'seconds' => 21600,
      'label' => 'Last 6 hours',
    ],
    '24h' => [
      'seconds' => 86400,
      'label' => 'Last 24 hours',
    ],
    '7d' => [
      'seconds' => 604800,
      'label' => 'Last 7 days',
    ],
  ];

  /**
   * Creates a new dashboard time range resolver instance.
   *
   * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
   *   The current request stack service.
   * @param \Drupal\Core\Routing\RouteMatchInterface $currentRouteMatch
   *   The current route match service.
   */
  public function __construct(
    private readonly RequestStack $requestStack,
    private readonly RouteMatchInterface $currentRouteMatch,
  ) {
  }

  /**
   * Resolves the active time range from the current request.
   *
   * @return \Drupal\native_observability_dashboard\ValueObject\TimeRange
   *   The resolved time range value object.
   */
  public function resolve(): TimeRange {
    $request = $this->requestStack->getCurrentRequest();
    $rangeKey = $request?->query->get('range', self::DEFAULT_RANGE);

    if (!is_string($rangeKey) || !isset(self::ALLOWED_RANGES[$rangeKey])) {
      $rangeKey = self::DEFAULT_RANGE;
    }

    $rangeDefinition = self::ALLOWED_RANGES[$rangeKey];
    $endTimestamp = time();
    $startTimestamp = $endTimestamp - (int) $rangeDefinition['seconds'];

    return new TimeRange(
      $startTimestamp,
      $endTimestamp,
      (string) $rangeDefinition['label'],
      $rangeKey,
    );
  }

  /**
   * Builds the UI options for the dashboard time range selector.
   *
   * @return array
   *   A list of range selector items.
   */
  public function buildSelectorItems(): array {
    $request = $this->requestStack->getCurrentRequest();
    $activeRange = $this->resolve()->getKey();
    $routeName = $this->currentRouteMatch->getRouteName() ?: '<current>';

    $items = [];

    foreach (self::ALLOWED_RANGES as $key => $definition) {
      $query = $request ? $request->query->all() : [];
      $query['range'] = $key;

      $items[] = [
        'key' => $key,
        'label' => $key,
        'title' => (string) $definition['label'],
        'is_active' => $activeRange === $key,
        'url' => Url::fromRoute($routeName, [], ['query' => $query])->toString(),
      ];
    }

    return $items;
  }

}
