<?php

/**
 * @file
 * Contains post_update hooks for ai_automators module.
 */

use Drupal\ai_automators\AiAutomatorStatusField;
use Drupal\Core\Config\Entity\ConfigEntityUpdater;
use Drupal\Core\Field\FieldConfigInterface;
use Drupal\field\FieldStorageConfigInterface;

/**
 * Adds enforced ai_automators dependencies to status field storage configs.
 */
function ai_automators_post_update_13001(&$sandbox) {
  \Drupal::state()->set('ai_automators.importing', TRUE);
  $config_entity_updater = \Drupal::classResolver(ConfigEntityUpdater::class);
  $callback = function (FieldStorageConfigInterface $field) {
    if ($field->getName() == AiAutomatorStatusField::FIELD_NAME) {
      $dependencies = $field->get('dependencies') ?? [];
      $modules = $dependencies['enforced']['module'] ?? [];
      if (in_array('ai_automators', $modules, TRUE)) {
        return FALSE;
      }
      $modules[] = 'ai_automators';
      sort($modules);
      $dependencies['enforced']['module'] = $modules;
      $field->set('dependencies', $dependencies);
      return TRUE;
    }
    return FALSE;
  };
  $config_entity_updater->update($sandbox, 'field_storage_config', $callback);
  \Drupal::state()->set('ai_automators.importing', FALSE);
}

/**
 * Adds enforced ai_automators dependencies to status field config entities.
 */
function ai_automators_post_update_13002(&$sandbox) {
  \Drupal::state()->set('ai_automators.importing', TRUE);
  $config_entity_updater = \Drupal::classResolver(ConfigEntityUpdater::class);
  $callback = function (FieldConfigInterface $field) {
    if ($field->getName() == AiAutomatorStatusField::FIELD_NAME) {
      $dependencies = $field->get('dependencies') ?? [];
      $modules = $dependencies['enforced']['module'] ?? [];
      if (in_array('ai_automators', $modules, TRUE)) {
        return FALSE;
      }
      $modules[] = 'ai_automators';
      sort($modules);
      $dependencies['enforced']['module'] = $modules;
      $field->set('dependencies', $dependencies);
      return TRUE;
    }
    return FALSE;
  };

  $config_entity_updater->update($sandbox, 'field_config', $callback);
  \Drupal::state()->set('ai_automators.importing', FALSE);
}

/**
 * Migrate Automator type settings to the standardized provider_config schema.
 *
 * Converts the old flat keys (ai_provider, ai_model, ai_provider_*)
 * stored by AiProviderFormHelper to the new provider_config structure
 * expected by the ai_provider_configuration form element.
 */
function ai_automators_post_update_20001(): void {
  $entityTypeManager = \Drupal::entityTypeManager();
  $storage = $entityTypeManager->getStorage('ai_automator');
  /** @var \Drupal\ai_automators\AiAutomatorInterface[] $automators */
  $automators = $storage->loadMultiple();
  $migratedCount = 0;
  $errorCount = 0;

  foreach ($automators as $automator) {
    try {
      $types = $automator->getAutomatorTypes();
      $changed = FALSE;

      foreach ($types as $type) {
        $config = $type->getConfiguration();
        $settings = $config['settings'] ?? [];

        // Skip if already migrated (new key exists).
        if (isset($settings['provider_config'])) {
          continue;
        }
        // Skip if there are no old flat keys to migrate.
        if (empty($settings['ai_provider'])) {
          continue;
        }

        // Build the new provider_config structure from the old flat keys.
        $providerConfig = [
          'provider' => $settings['ai_provider'] ?? '',
          'model'    => $settings['ai_model'] ?? '',
          'config'   => [],
        ];
        unset($settings['ai_provider'], $settings['ai_model']);

        // Identify secondary providers.
        // Currently only 'audio' is known to be used by VideoToText.
        $secondaryProviders = ['audio'];
        $secondaryConfigs = [];

        foreach ($secondaryProviders as $suffix) {
          if (isset($settings['ai_provider_' . $suffix])) {
            $secondaryConfigs[$suffix] = [
              'provider' => $settings['ai_provider_' . $suffix],
              'model' => $settings['ai_model_' . $suffix] ?? '',
              'config' => [],
            ];
            unset($settings['ai_provider_' . $suffix], $settings['ai_model_' . $suffix]);
          }
        }

        // Iterate over remaining settings to find configs.
        foreach (array_keys($settings) as $key) {
          // Main provider config (starts with ai_provider_).
          // Since secondary provider IDs (e.g. ai_provider_audio) were already
          // removed above, anything starting with ai_provider_ here
          // is a config setting.
          if (str_starts_with($key, 'ai_provider_')) {
            $configKey = substr($key, 12);
            $providerConfig['config'][$configKey] = $settings[$key];
            unset($settings[$key]);
          }
          // Secondary provider config (starts with configuration_).
          elseif (str_starts_with($key, 'configuration_')) {
            // Check if it matches any found secondary provider suffix.
            // Format: configuration_{setting}_{suffix}.
            foreach ($secondaryConfigs as $suffix => $data) {
              $suffixString = '_' . $suffix;
              if (str_ends_with($key, $suffixString)) {
                // Extract setting name:
                // remove 'configuration_' prefix and suffix.
                $configName = substr($key, 14, -strlen($suffixString));
                if (!empty($configName)) {
                  $secondaryConfigs[$suffix]['config'][$configName] = $settings[$key];
                  unset($settings[$key]);
                }
              }
            }
          }
        }

        $settings['provider_config'] = $providerConfig;
        foreach ($secondaryConfigs as $suffix => $data) {
          $settings['provider_config_' . $suffix] = $data;
        }

        $config['settings'] = $settings;
        $type->setConfiguration($config);
        $changed = TRUE;
      }

      if ($changed) {
        $automator->save();
        $migratedCount++;
      }
    }
    catch (\Exception $e) {
      $errorCount++;
      \Drupal::logger('ai_automators')->error(
        'Failed to migrate provider config for Automator @id: @message',
        ['@id' => $automator->id(), '@message' => $e->getMessage()]
      );
    }
  }

  if ($migratedCount > 0) {
    \Drupal::messenger()->addStatus(t(
      'Migrated provider configuration for @count AI Automator(s) to the new standardized schema.',
      ['@count' => $migratedCount]
    ));
  }

  if ($errorCount > 0) {
    \Drupal::messenger()->addWarning(t(
      '@count AI Automator(s) could not be migrated. Please check the logs.',
      ['@count' => $errorCount]
    ));
  }
}
