<?php

declare(strict_types=1);

namespace Drupal\flowdrop_playground\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Url;
use Drupal\flowdrop_session\Service\SessionService;
use Drupal\flowdrop_ui_components\Service\FlowDropEndpointConfigService;
use Drupal\flowdrop_workflow\Entity\FlowDropWorkflow;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Controller for FlowDrop Playground UI pages.
 *
 * @internal This class is not part of the public API and may change without notice.
 */
class PlaygroundController extends ControllerBase {

  /**
   * The FlowDrop endpoint config service.
   *
   * @var \Drupal\flowdrop_ui_components\Service\FlowDropEndpointConfigService
   */
  protected FlowDropEndpointConfigService $endpointConfigService;

  /**
   * The session service.
   *
   * @var \Drupal\flowdrop_session\Service\SessionService
   */
  protected SessionService $sessionService;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container): static {
    $instance = new static();
    $instance->endpointConfigService = $container->get('flowdrop_ui_components.endpoint_config');
    $instance->sessionService = $container->get('flowdrop_session.service');
    return $instance;
  }

  /**
   * Renders the playground page for a workflow.
   *
   * Uses fullscreen mode with custom HTML/page templates to provide an
   * immersive experience without Drupal's admin chrome (toolbar, menus, etc.).
   * This approach is similar to the workflow editor and avoids modal-related
   * issues with Drupal's page rendering.
   *
   * @param \Drupal\flowdrop_workflow\Entity\FlowDropWorkflow $flowdrop_workflow
   *   The workflow entity.
   *
   * @return array<string, mixed>
   *   Render array for the playground page.
   */
  public function playgroundPage(FlowDropWorkflow $flowdrop_workflow): array {
    // Prepare workflow data for the frontend.
    $workflow_data = [
      'id' => $flowdrop_workflow->id(),
      'label' => $flowdrop_workflow->label(),
      'description' => $flowdrop_workflow->getDescription(),
      'nodes' => $flowdrop_workflow->getNodes(),
      'edges' => $flowdrop_workflow->getEdges(),
      'metadata' => $flowdrop_workflow->getMetadata(),
      'created' => $flowdrop_workflow->getCreated(),
      'changed' => $flowdrop_workflow->getChanged(),
    ];

    // Build the API base URL.
    $url_options = [
      'absolute' => TRUE,
      'language' => $this->languageManager()->getCurrentLanguage(),
    ];
    $base_url = Url::fromRoute('<front>', [], $url_options)->toString() . '/api/flowdrop';

    // Generate endpoint configuration.
    $endpoint_config = $this->endpointConfigService->generateEndpointConfig($base_url);

    // Build back URL - navigates to workflow listing when back button clicked.
    $back_url = Url::fromRoute('flowdrop.workflows')->toString();

    // Build editor URL - navigates to workflow editor when edit button clicked.
    $editor_url = Url::fromRoute('flowdrop.workflow.editor', [
      'flowdrop_workflow' => $flowdrop_workflow->id(),
    ])->toString();

    // Get the most recent session for this workflow to auto-select it.
    // Sessions are returned sorted by created DESC (most recent first).
    $initial_session_id = NULL;
    $workflow_id = $flowdrop_workflow->id();
    if ($workflow_id !== NULL) {
      $sessions = $this->sessionService->getSessionsForWorkflow(
        $workflow_id,
        NULL,
        1
      );
      if (!empty($sessions)) {
        $most_recent_session = reset($sessions);
        $initial_session_id = $most_recent_session->uuid();
      }
    }

    // Check if workflow has a chat input node to determine UI configuration.
    // Workflows without chat input should hide the text input and only show
    // the Run button.
    $has_chat_input = $this->sessionService->hasChatInputNode($flowdrop_workflow);

    // Determine if auto-run should be enabled.
    // Only auto-run if: config is enabled AND workflow has no chat input.
    $config = $this->config("flowdrop_playground.settings");
    $auto_run_enabled = $config->get("auto_run") ?? TRUE;
    $auto_run = $auto_run_enabled && !$has_chat_input;

    // Build component props.
    $props = [
      'workflow' => $workflow_data,
      'endpoint_config' => $endpoint_config,
      'container_id' => 'flowdrop-playground-' . $flowdrop_workflow->id(),
      'mode' => 'standalone',
      'height' => '100vh',
      'width' => '100vw',
      'back_url' => $back_url,
      'editor_url' => $editor_url,
      'workflow_name' => $flowdrop_workflow->label(),
      // Show chat input only if workflow has a chat input node.
      'show_chat_input' => $has_chat_input,
      // Always show run button.
      'show_run_button' => TRUE,
      // Auto-run if enabled and workflow has no chat input.
      'auto_run' => $auto_run,
    ];

    // Add initial session ID if a session exists.
    if ($initial_session_id !== NULL) {
      $props['initial_session_id'] = $initial_session_id;
    }

    // Render using the SDC playground component in standalone mode.
    // The page uses custom HTML/page templates (see src/Hook/Hooks.php)
    // to remove Drupal's admin chrome for a clean fullscreen experience.
    // "standalone" mode renders the playground without any wrapper/modal.
    $build['content'] = [
      '#type' => 'component',
      '#component' => 'flowdrop_ui_components:playground',
      '#props' => $props,
      '#attached' => [
        'library' => [
          'flowdrop_playground/playground',
        ],
      ],
    ];

    return $build;
  }

  /**
   * Title callback for the playground page.
   *
   * @param \Drupal\flowdrop_workflow\Entity\FlowDropWorkflow $flowdrop_workflow
   *   The workflow entity.
   *
   * @return string
   *   The page title.
   */
  public function playgroundTitle(FlowDropWorkflow $flowdrop_workflow): string {
    return $this->t('Playground - @name', ['@name' => $flowdrop_workflow->label()])->__toString();
  }

}
