<?php

declare(strict_types=1);

namespace Drupal\native_observability_dashboard\Controller\Dashboard;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Routing\UrlGeneratorInterface;
use Drupal\native_observability_dashboard\Service\DashboardOverviewBuilder;
use Drupal\native_observability_dashboard\Service\DashboardTimeRangeResolver;

/**
 * Returns the Overview tab for the Native Observability dashboard.
 */
final class OverviewController extends ControllerBase {

  /**
   * Creates a new overview controller instance.
   *
   * @param \Drupal\native_observability_dashboard\Service\DashboardOverviewBuilder $overviewBuilder
   *   The overview dashboard builder service.
   * @param \Drupal\native_observability_dashboard\Service\DashboardTimeRangeResolver $timeRangeResolver
   *   The dashboard time range resolver service.
   * @param \Drupal\Core\Routing\UrlGeneratorInterface $urlGenerator
   *   The URL generator service.
   */
  public function __construct(
    private readonly DashboardOverviewBuilder $overviewBuilder,
    private readonly DashboardTimeRangeResolver $timeRangeResolver,
    private readonly UrlGeneratorInterface $urlGenerator,
  ) {}

  /**
   * Builds the overview dashboard tab.
   *
   * @return array
   *   A render array for the overview tab.
   */
  public function overview(): array {
    $timeRange = $this->timeRangeResolver->resolve();
    $dashboard = $this->overviewBuilder->build($timeRange);

    return [
      '#theme' => 'native_observability_dashboard_overview',
      '#dashboard' => $dashboard,
      '#range_selector' => $this->timeRangeResolver->buildSelectorItems(),
      '#active_range' => $timeRange->getKey(),
      '#cache' => [
        'contexts' => ['url.query_args:range'],
      ],
      '#attached' => [
        'library' => [
          'native_observability_dashboard/dashboard',
        ],
        'drupalSettings' => [
          'nativeObservabilityDashboard' => [
            'primaryKpis' => $this->buildPrimaryKpiChartSettings($dashboard),
            'timelines' => $this->buildTimelineChartSettings($dashboard),
            'technicalInsightsExplorer' => $this->buildTechnicalInsightsExplorerSettings($dashboard),
            'externalRequestsPreview' => $this->buildExternalRequestsPreviewChartSettings($dashboard),
            'breakdownDonut' => $this->buildBreakdownDonutSettings($dashboard),
          ],
        ],
      ],
    ];
  }

  /**
   * Extracts chart-ready settings for the primary KPI cards.
   *
   * @param array $dashboard
   *   The full dashboard payload.
   *
   * @return array
   *   A keyed array of chart settings grouped by chart id.
   */
  private function buildPrimaryKpiChartSettings(array $dashboard): array {
    $settings = [];
    $section = $dashboard['sections']['primary_kpis'] ?? NULL;

    if (!is_array($section) || empty($section['enabled']) || empty($section['cards'])) {
      return $settings;
    }

    foreach ($section['cards'] as $card) {
      if (empty($card['chart_id']) || empty($card['timeseries']) || !is_array($card['timeseries'])) {
        continue;
      }

      $settings[$card['chart_id']] = [
        'metric_id' => $card['id'] ?? '',
        'title' => $card['title'] ?? '',
        'color' => $card['color'] ?? 'blue',
        'series' => array_values($card['timeseries']),
      ];
    }

    return $settings;
  }

  /**
   * Extracts chart-ready settings for all timeline-based sections.
   *
   * @param array $dashboard
   *   The full dashboard payload.
   *
   * @return array
   *   A keyed array of chart settings grouped by chart id.
   */
  private function buildTimelineChartSettings(array $dashboard): array {
    $settings = [];

    foreach (['request_timeline', 'ajax_activity'] as $sectionKey) {
      $section = $dashboard['sections'][$sectionKey] ?? NULL;

      if (!is_array($section) || empty($section['enabled']) || empty($section['chart_id'])) {
        continue;
      }

      $settings[$section['chart_id']] = [
        'chart_id' => $section['chart_id'],
        'title' => $section['title'] ?? '',
        'subtitle' => $section['subtitle'] ?? '',
        'series' => $section['series'] ?? [],
      ];
    }

    return $settings;
  }

  /**
   * Extracts technical explorer settings for client-side table interactions.
   *
   * @param array $dashboard
   *   The full dashboard payload.
   *
   * @return array
   *   The technical explorer settings payload.
   */
  private function buildTechnicalInsightsExplorerSettings(array $dashboard): array {
    $section = $dashboard['sections']['technical_insights'] ?? NULL;

    if (!is_array($section) || empty($section['enabled'])) {
      return [];
    }

    $datasets = $section['datasets'] ?? [];

    foreach ($datasets as $datasetKey => &$dataset) {
      $dataset['actions'] = [
        'export' => $this->urlGenerator->generateFromRoute(
          'native_observability_dashboard.export',
          ['dataset' => $datasetKey]
        ),
        'flush' => $this->urlGenerator->generateFromRoute(
          'native_observability_dashboard.flush',
          ['dataset' => $datasetKey]
        ),
      ];
    }
    unset($dataset);

    return [
      'title' => $section['title'] ?? '',
      'time_range' => $section['time_range'] ?? '',
      'datasets' => $datasets,
    ];
  }

  /**
   * Extracts breakdown donut settings for the Response Time KPI card.
   *
   * @param array $dashboard
   *   The full dashboard payload.
   *
   * @return array
   *   The breakdown donut settings or an empty array when unavailable.
   */
  private function buildBreakdownDonutSettings(array $dashboard): array {
    $cards = $dashboard['sections']['primary_kpis']['cards'] ?? [];

    foreach ($cards as $card) {
      if (($card['id'] ?? '') !== 'response_time') {
        continue;
      }

      $breakdown = $card['breakdown'] ?? [];

      if (empty($breakdown['enabled'])) {
        return [];
      }

      return [
        'chart_id' => (string) ($breakdown['chart_id'] ?? ''),
        'total_ms' => (float) ($breakdown['total_ms'] ?? 0),
        'series' => $breakdown['series'] ?? [],
      ];
    }

    return [];
  }

  /**
   * Builds chart settings for the external requests preview block.
   *
   * @param array $dashboard
   *   The full dashboard payload.
   *
   * @return array
   *   The preview chart settings or an empty array when unavailable.
   */
  private function buildExternalRequestsPreviewChartSettings(array $dashboard): array {
    $section = $dashboard['sections']['technical_insights'] ?? NULL;
    $dataset = is_array($section) ? ($section['datasets']['external_requests'] ?? NULL) : NULL;

    if (!is_array($dataset) || empty($dataset['rows']) || !is_array($dataset['rows'])) {
      return [];
    }

    $rows = array_slice(array_values($dataset['rows']), 0, 8);
    $chartId = 'native-observability-external-requests-preview';

    return [
      'chart_id' => $chartId,
      'title' => 'External Requests',
      'series' => array_map(static function (array $row): array {
        return [
          'name' => (string) ($row['target'] ?? 'Unknown target'),
          'value' => (int) ($row['request_count_raw'] ?? 0),
        ];
      }, $rows),
    ];
  }

}
