<?php

declare(strict_types=1);

namespace Drupal\native_observability_cache_observer\Controller;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Render\Markup;
use Drupal\native_observability_cache_observer\Service\CacheObserverStorage;
use Symfony\Component\DependencyInjection\Attribute\Autowire;

/**
 * Builds the cache observer report page.
 */
final class CacheObserverController extends ControllerBase {

  /**
   * Creates a new cache observer controller instance.
   */
  public function __construct(
    private readonly CacheObserverStorage $storage,
    #[Autowire(service: 'config.factory')]
    private readonly ConfigFactoryInterface $cacheObserverConfigFactory,
  ) {
  }

  /**
   * Builds the cache observer report page.
   */
  public function report(): array {
    $config = $this->cacheObserverConfigFactory->get('native_observability_cache_observer.settings');
    $summary = $this->storage->getSummary(24);
    $rows = $this->storage->getRecentEvents((int) ($config->get('report_limit') ?? 100));

    $build['summary'] = [
      '#type' => 'container',
      '#attributes' => ['class' => ['native-observability-cache-observer-summary']],
    ];

    foreach ([
      'total_events' => $this->t('Observed events (24h)'),
      'page_cache_hits' => $this->t('Page cache hits'),
      'page_cache_misses' => $this->t('Page cache misses'),
      'dynamic_cache_hits' => $this->t('Dynamic cache hits'),
      'dynamic_cache_misses' => $this->t('Dynamic cache misses'),
      'invalidation_events' => $this->t('Invalidation events'),
      'invalidated_tags' => $this->t('Invalidated tags'),
    ] as $key => $label) {
      $build['summary'][$key] = [
        '#type' => 'item',
        '#title' => $label,
        '#markup' => '<strong>' . (string) ($summary[$key] ?? 0) . '</strong>',
      ];
    }

    $table_rows = [];
    foreach ($rows as $row) {
      $payload_markup = '<pre style="white-space: pre-wrap; margin: 0;">'
        . $this->escape(json_encode($row['payload'], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) ?: '{}')
        . '</pre>';

      $table_rows[] = [
        'data' => [
          $row['created_at'],
          $row['event_type'],
          $row['cache_layer'],
          $row['status'],
          $row['method'],
          $row['path'],
          $row['route_name'],
          $row['request_id'],
          (string) $row['tag_count'],
          (string) $row['context_count'],
          (string) $row['max_age'],
          Markup::create($payload_markup),
        ],
      ];
    }

    $build['events'] = [
      '#type' => 'table',
      '#header' => [
        $this->t('Created'),
        $this->t('Event type'),
        $this->t('Layer'),
        $this->t('Status'),
        $this->t('Method'),
        $this->t('Path'),
        $this->t('Route'),
        $this->t('Request ID'),
        $this->t('Tags'),
        $this->t('Contexts'),
        $this->t('Max-age'),
        $this->t('Payload'),
      ],
      '#rows' => $table_rows,
      '#empty' => $this->t('No cache observer events have been recorded yet.'),
      '#cache' => ['max-age' => 0],
    ];

    return $build;
  }

}
