<?php

declare(strict_types=1);

namespace Drupal\flowdrop\DTO\ConfigEdit;

/**
 * Value object for external edit link configuration.
 *
 * Represents the configuration for opening an external configuration form
 * (e.g., admin UI) for a node. This is useful when:
 * - Configuration is managed by a 3rd party system
 * - You need a specialized UI not supported by FlowDrop forms
 * - Config includes complex nested structures or file uploads.
 *
 * @see config-edit.md for full specification
 *
 * @api
 */
final class ExternalEditLink {

  /**
   * Constructs an ExternalEditLink.
   *
   * @param string $url
   *   The URL template for the external edit form.
   *   Supports template variables like {nodeTypeId}, {instanceId}.
   * @param string $label
   *   Human-readable label for the link (e.g., "Configure in Admin Portal").
   * @param string $icon
   *   Icon identifier (e.g., "mdi:cog", "mdi:open-in-new").
   * @param string $description
   *   Description text explaining what the link does.
   * @param array<string, string> $parameterMapping
   *   Maps URL template variables to node data paths.
   *   Example: ["trigger_config_id" => "config.trigger_config_id"].
   * @param bool $openInNewTab
   *   Whether to open the link in a new browser tab. Default TRUE.
   */
  public function __construct(
    public readonly string $url,
    public readonly string $label = "Configure",
    public readonly string $icon = "mdi:cog",
    public readonly string $description = "",
    public readonly array $parameterMapping = [],
    public readonly bool $openInNewTab = TRUE,
  ) {}

  /**
   * Creates an instance from an array.
   *
   * @param array<string, mixed> $data
   *   The array data to create the instance from.
   *
   * @return self
   *   The created instance.
   */
  public static function fromArray(array $data): self {
    return new self(
      url: $data["url"] ?? "",
      label: $data["label"] ?? "Configure",
      icon: $data["icon"] ?? "mdi:cog",
      description: $data["description"] ?? "",
      parameterMapping: $data["parameterMapping"] ?? [],
      openInNewTab: $data["openInNewTab"] ?? TRUE,
    );
  }

  /**
   * Converts the object to an array suitable for JSON serialization.
   *
   * @return array<string, mixed>
   *   The array representation.
   */
  public function toArray(): array {
    return [
      "url" => $this->url,
      "label" => $this->label,
      "icon" => $this->icon,
      "description" => $this->description,
      "parameterMapping" => $this->parameterMapping,
      "openInNewTab" => $this->openInNewTab,
    ];
  }

}
