<?php

namespace Drupal\dfg_3dviewer\Drush\Commands;

use Drupal\dfg_3dviewer\Service\Dfg3dViewerConfigApplier;
use Drush\Attributes as CLI;
use Drush\Commands\DrushCommands;

/**
 * Drush commands for DFG 3D Viewer configuration.
 */
final class Dfg3dViewerCommands extends DrushCommands {

  public function __construct(
    protected Dfg3dViewerConfigApplier $configApplier,
  ) {
    parent::__construct();
  }

  /**
   * Applies DFG 3D Viewer settings (local dev preset by default).
   */
  #[CLI\Command(name: 'dfg-3dviewer:configure', aliases: ['dfg3dv-config'])]
  #[CLI\Option(name: 'main-url', description: 'Main URL')]
  #[CLI\Option(name: 'basenamespace', description: 'Default base namespace')]
  #[CLI\Option(name: 'metadata-url', description: 'Metadata URL')]
  #[CLI\Option(name: 'json-export-base-url', description: 'JSON export base URL')]
  #[CLI\Option(name: 'container', description: 'Container ID')]
  #[CLI\Option(name: 'entitybundle', description: 'Entity bundle ID')]
  #[CLI\Option(name: 'viewer-file-upload', description: 'Viewer file upload field ID')]
  #[CLI\Option(name: 'viewer-file-name', description: 'Viewer file name field ID')]
  #[CLI\Option(name: 'api-3d-file-field', description: 'API 3D file field')]
  #[CLI\Option(name: 'image-generation', description: 'Image generation field ID')]
  #[CLI\Option(name: 'field-df', description: 'Field DF')]
  #[CLI\Option(name: 'export-viewer', description: 'Export viewer field')]
  #[CLI\Option(name: 'export-viewer-url', description: 'Export viewer URL')]
  #[CLI\Option(name: 'lightweight', description: 'Enable lightweight mode (0 or 1)')]
  #[CLI\Option(name: 'scale-container-x', description: 'Scale container X')]
  #[CLI\Option(name: 'scale-container-y', description: 'Scale container Y')]
  #[CLI\Option(name: 'gallery-container', description: 'Gallery container element name')]
  #[CLI\Option(name: 'gallery-image-class', description: 'Gallery image class name')]
  #[CLI\Option(name: 'gallery-image-id', description: 'Gallery image ID name')]
  #[CLI\Option(name: 'base-module-path', description: 'Path for the Viewer module')]
  #[CLI\Option(name: 'entity-id-uri', description: 'Regex for entity ID')]
  #[CLI\Option(name: 'view-entity-path', description: 'Path with navigate content')]
  #[CLI\Option(name: 'attribute-id', description: 'WissKI attribute ID')]
  #[CLI\Usage(name: 'drush dfg-3dviewer:configure', description: 'Apply the bundled local development preset')]
  #[CLI\Usage(name: 'drush dfg-3dviewer:configure --main-url=https://example.test/', description: 'Apply preset with one override')]
  public function applyConfiguration(
    array $options = [
      'main-url' => self::OPT,
      'basenamespace' => self::OPT,
      'metadata-url' => self::OPT,
      'json-export-base-url' => self::OPT,
      'container' => self::OPT,
      'entitybundle' => self::OPT,
      'viewer-file-upload' => self::OPT,
      'viewer-file-name' => self::OPT,
      'api-3d-file-field' => self::OPT,
      'image-generation' => self::OPT,
      'field-df' => self::OPT,
      'export-viewer' => self::OPT,
      'export-viewer-url' => self::OPT,
      'lightweight' => self::OPT,
      'scale-container-x' => self::OPT,
      'scale-container-y' => self::OPT,
      'gallery-container' => self::OPT,
      'gallery-image-class' => self::OPT,
      'gallery-image-id' => self::OPT,
      'base-module-path' => self::OPT,
      'entity-id-uri' => self::OPT,
      'view-entity-path' => self::OPT,
      'attribute-id' => self::OPT,
    ],
  ): void {
    $values = $this->configApplier->getDevPreset();
    $option_map = [
      'main-url' => 'dfg_3dviewer_main_url',
      'basenamespace' => 'dfg_3dviewer_basenamespace',
      'metadata-url' => 'dfg_3dviewer_metadata_url',
      'json-export-base-url' => 'dfg_3dviewer_json_export_base_url',
      'container' => 'dfg_3dviewer_container',
      'entitybundle' => 'dfg_3dviewer_entitybundle',
      'viewer-file-upload' => 'dfg_3dviewer_viewer_file_upload',
      'viewer-file-name' => 'dfg_3dviewer_viewer_file_name',
      'api-3d-file-field' => 'dfg_3dviewer_api_3d_file_field',
      'image-generation' => 'dfg_3dviewer_image_generation',
      'field-df' => 'dfg_3dviewer_field_df',
      'export-viewer' => 'dfg_3dviewer_export_viewer',
      'export-viewer-url' => 'dfg_3dviewer_export_viewer_url',
      'lightweight' => 'dfg_3dviewer_lightweight',
      'scale-container-x' => 'dfg_3dviewer_scale_container_x',
      'scale-container-y' => 'dfg_3dviewer_scale_container_y',
      'gallery-container' => 'dfg_3dviewer_gallery_container',
      'gallery-image-class' => 'dfg_3dviewer_gallery_image_class',
      'gallery-image-id' => 'dfg_3dviewer_gallery_image_id',
      'base-module-path' => 'dfg_3dviewer_base_module_path',
      'entity-id-uri' => 'dfg_3dviewer_entity_id_uri',
      'view-entity-path' => 'dfg_3dviewer_view_entity_path',
      'attribute-id' => 'dfg_3dviewer_attribute_id',
    ];

    foreach ($option_map as $option => $key) {
      if ($options[$option] !== NULL) {
        $values[$key] = $this->normalizeOptionValue($key, $options[$option]);
      }
    }

    $prepared = $this->configApplier->prepareValues($values);
    $missing = $this->configApplier->validateRequired($prepared);
    if ($missing !== []) {
      throw new \InvalidArgumentException('Missing required settings: ' . implode(', ', $missing));
    }

    $this->configApplier->apply($values);
    $this->logger()->success('DFG 3D Viewer settings saved.');
  }

  /**
   * Converts CLI option values to the expected config types.
   */
  protected function normalizeOptionValue(string $key, mixed $value): mixed {
    if ($key === 'dfg_3dviewer_lightweight') {
      return filter_var($value, FILTER_VALIDATE_BOOLEAN);
    }

    return (string) $value;
  }

}
