<?php

namespace Drupal\api_monitor_client\Controller;

use Drupal\api_monitor_client\ApiSnifferService;
use Drupal\api_monitor_client\ApiSwaggerManager;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;

/**
 * Controller for the API detail and render swagger.
 */
class SwaggerController extends ControllerBase {

  /**
   * Construct SwaggerController.
   *
   * @param \Drupal\api_monitor_client\ApiSnifferService $apiRunner
   *   The API sniffer service.
   * @param \Drupal\api_monitor_client\ApiSwaggerManager $apiSwaggerManager
   *   The API swagger manager.
   */
  public function __construct(
    protected readonly ApiSnifferService $apiRunner,
    private readonly ApiSwaggerManager $apiSwaggerManager,
  ) {
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('api_monitor_client.sniffer'),
      $container->get('api_monitor_client.swagger_manager')
    );
  }

  /**
   * Generates the OpenAPI specification for the given API ID in JSON format.
   *
   * @param string $provider_id
   *   The unique identifier of the provider.
   * @param string $api_id
   *   The unique identifier of the API.
   *
   * @return \Symfony\Component\HttpFoundation\JsonResponse
   *   A JSON response containing the OpenAPI specification, or an error message
   *   if the API is not found.
   */
  public function openApiJson(string $provider_id, string $api_id) :JsonResponse {
    /** @var \Drupal\api_monitor_client\Entity\ApiMonitorProviderInterface $provider */
    $provider = $this->entityTypeManager()->getStorage('api_monitor_provider')->load($provider_id);
    if (!$provider) {
      return new JsonResponse(['error' => 'Provider non trovato'], 404);
    }

    $discovery = $this->apiRunner->getApiDiscovery($provider);
    if (empty($discovery)) {
        return new JsonResponse(['error' => 'Impossibile recuperare il discovery'], 500);
    }

    $api = array_values(array_filter($discovery, fn($item) => ($item['id'] ?? NULL) === $api_id))[0] ?? NULL;
    if (empty($api)) {
      return new JsonResponse(['error' => 'API non trovata'], 404);
    }
    $spec = $this->apiSwaggerManager->swagger($api, $api_id, $provider);
    return new JsonResponse($spec);
  }

  /**
   * Renders the Swagger UI for the given API ID.
   *
   * @param string $provider_id
   *   The unique identifier of the provider.
   * @param string $api_id
   *   The unique identifier of the API.
   *
   * @return array
   *   Render array.
   */
  public function view(string $provider_id, string $api_id) {
    return [
      '#type' => 'container',
      '#attributes' => ['id' => 'swagger-ui'],
      '#attached' => [
        'library' => ['api_monitor_client/swagger_ui'],
        'drupalSettings' => [
          'api_monitor_client' => [
            'current_provider_id' => $provider_id,
            'current_api_id' => $api_id,
          ],
        ],
      ],
    ];
  }

}
