<?php

declare(strict_types=1);

namespace Drupal\flowdrop_ui_components\Helper;

use Drupal\Core\Config\ConfigBase;

/**
 * Combines the split UI config keys into the JSON shape the SDC expects.
 *
 * The Drupal-side config is split into `default_settings` (JSON string),
 * `exposed_categories` (sequence) and the draft keys (`draft_auto_save`,
 * `draft_storage`) so each can have its own form widget, but the Svelte side
 * wants a single JSON document of the form
 * `{ "defaults": {...}, "exposed": [...], "drafts": {...} }`. This helper does
 * that re-assembly and is the only place that knows about the wire shape.
 *
 * @internal Not part of the public API.
 */
final class UiConfigBuilder {

  /**
   * Build the combined ui_config JSON string from module config.
   *
   * @param \Drupal\Core\Config\ConfigBase $config
   *   The `flowdrop_ui_components.settings` config object.
   *
   * @return string
   *   JSON string with `defaults` and `exposed` keys, or empty string when no
   *   config has been set (so callers can skip rendering the data attribute).
   */
  public static function fromConfig(ConfigBase $config): string {
    $defaults_raw = (string) ($config->get('default_settings') ?? '');
    $exposed = $config->get('exposed_categories');
    $exposed = is_array($exposed) ? array_values($exposed) : [];

    $defaults = NULL;
    if ($defaults_raw !== '') {
      $decoded = json_decode($defaults_raw, TRUE);
      if (is_array($decoded)) {
        $defaults = $decoded;
      }
    }

    // Draft persistence. Missing keys (sites installed before these existed)
    // fall back to the same defaults editor.js applies when the attribute is
    // absent entirely: auto-save on, tab-scoped sessionStorage.
    $draft_auto_save = $config->get('draft_auto_save');
    $draft_storage = $config->get('draft_storage');
    $has_draft_config = $draft_auto_save !== NULL || $draft_storage !== NULL;

    if ($defaults === NULL && $exposed === [] && !$has_draft_config) {
      return '';
    }

    return (string) json_encode([
      // Use stdClass so an empty defaults map serialises as `{}` not `[]`.
      'defaults' => $defaults ?? new \stdClass(),
      'exposed' => $exposed,
      'drafts' => [
        'autoSave' => $draft_auto_save ?? TRUE,
        'storage' => in_array($draft_storage, ['local', 'session'], TRUE) ? $draft_storage : 'session',
      ],
    ], JSON_UNESCAPED_SLASHES);
  }

}
