<?php

namespace Drupal\rufi_structure;

use Drupal\Component\Utility\Crypt;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\StorageInterface;
use Drupal\locale\LocaleConfigManager;
use Drupal\language\ConfigurableLanguageManagerInterface;
use Psr\Log\LoggerInterface;
use Drupal\Component\Uuid\UuidInterface;

class ConfigTranslationRepair {

  public function __construct(
    protected StorageInterface $configStorage,
    protected ConfigFactoryInterface $configFactory,
    protected LocaleConfigManager $localeConfigManager,
    protected ConfigurableLanguageManagerInterface $languageManager,
    protected UuidInterface $uuid,
    protected LoggerInterface $logger,
  ) {}

  /**
   * Repairs config langcodes and rebuilds config translations from locale.
   *
   * @param string|null $targetLangcode
   *   Target language, e.g. 'de'. If NULL, the default site language is used.
   *
   * @return array
   *   List of processed config names.
   */
  public function repair(array $config_names, ?string $targetLangcode = NULL): array {
    $targetLangcode = $targetLangcode ?: $this->languageManager->getDefaultLanguage()->getId();
    $processed = [];

    foreach ($config_names as $name) {
      $config = $this->configFactory->getEditable($name);

      if ($config->isNew()) {
        continue;
      }

      $data = $config->getRawData();
      $langcode = $data['langcode'] ?? NULL;

      // Create missing config hash, to make config translatable.
      if (!array_key_exists('_core', $data)) {
        $config->set('_core', ['default_config_hash' => Crypt::hashBase64(serialize($data)),]);
      }
      if (!array_key_exists('uuid', $data)) {
        $config->set('uuid', $this->uuid->generate());
      }
      $config->save();

      // Only process configs that currently look English or have no langcode.
      if ($langcode !== 'en' && $langcode !== NULL) {
        continue;
      }

      // Only process configs that Drupal considers translatable/supported.
      if (!$this->localeConfigManager->isSupported($name)) {
        continue;
      }

      $processed[] = $name;
    }

    if ($processed) {
      // Rebuild language overrides from translations stored in locale.
      $this->localeConfigManager->updateConfigTranslations($processed, [$targetLangcode]);
    }

    $this->logger->info('Processed @count configuration objects for config translation repair.', [
      '@count' => count($processed),
    ]);

    return $processed;
  }

}
