<?php

namespace Drupal\nodehive_dam\Plugin\Field\FieldWidget;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\media\Entity\Media;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Plugin implementation of the 'dam_media_widget' widget.
 *
 * @FieldWidget(
 *   id = "dam_media_widget",
 *   label = @Translation("DAM Media Browser"),
 *   description = @Translation("Browse and select media from the Digital Asset Management interface."),
 *   field_types = {
 *     "entity_reference"
 *   },
 *   multiple_values = TRUE
 * )
 */
class DamMediaWidget extends WidgetBase implements ContainerFactoryPluginInterface {

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The renderer.
   *
   * @var \Drupal\Core\Render\RendererInterface
   */
  protected $renderer;

  /**
   * Constructs a DamMediaWidget object.
   */
  public function __construct(
    $plugin_id,
    $plugin_definition,
    FieldDefinitionInterface $field_definition,
    array $settings,
    array $third_party_settings,
    EntityTypeManagerInterface $entity_type_manager,
    RendererInterface $renderer,
  ) {
    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);
    $this->entityTypeManager = $entity_type_manager;
    $this->renderer = $renderer;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $plugin_id,
      $plugin_definition,
      $configuration['field_definition'],
      $configuration['settings'],
      $configuration['third_party_settings'],
      $container->get('entity_type.manager'),
      $container->get('renderer')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function settingsSummary() {
    $summary = [];

    // Get allowed bundles from field configuration.
    $handler_settings = $this->fieldDefinition->getSetting('handler_settings');
    if (!empty($handler_settings['target_bundles'])) {
      $allowed_bundles = array_keys($handler_settings['target_bundles']);
      $bundles = $this->entityTypeManager->getStorage('media_type')->loadMultiple($allowed_bundles);
      $labels = array_map(function ($bundle) {
        return $bundle->label();
      }, $bundles);
      $summary[] = $this->t('Allowed types: @types', ['@types' => implode(', ', $labels)]);
    }
    else {
      $summary[] = $this->t('All media types allowed');
    }

    return $summary;
  }

  /**
   * {@inheritdoc}
   */
  public static function isApplicable(FieldDefinitionInterface $field_definition) {
    // Only show this widget for entity reference fields targeting media.
    $target_type = $field_definition->getFieldStorageDefinition()->getSetting('target_type');
    return $target_type === 'media';
  }

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    // This widget handles all values at once (multiple_values = TRUE).
    $field_name = $this->fieldDefinition->getName();
    $cardinality = $this->fieldDefinition->getFieldStorageDefinition()->getCardinality();
    $is_multiple = $cardinality !== 1;

    // Get allowed bundles from field configuration (handler settings).
    $handler_settings = $this->fieldDefinition->getSetting('handler_settings');
    $field_allowed_bundles = [];
    if (!empty($handler_settings['target_bundles'])) {
      $field_allowed_bundles = array_keys($handler_settings['target_bundles']);
    }

    // Get current values.
    $current_ids = [];
    foreach ($items as $item) {
      if ($item->target_id) {
        $current_ids[] = $item->target_id;
      }
    }

    // Load existing media entities.
    $current_media = [];
    if (!empty($current_ids)) {
      $current_media = $this->entityTypeManager->getStorage('media')->loadMultiple($current_ids);
    }

    // Build the widget element.
    $element['#type'] = 'container';
    $element['#attributes']['class'][] = 'dam-widget';
    $element['#attributes']['data-field-name'] = $field_name;
    $element['#attributes']['data-cardinality'] = $cardinality;
    $element['#attached']['library'][] = 'nodehive_dam/widget';

    // Hidden field to store selected media IDs.
    $element['target_ids'] = [
      '#type' => 'hidden',
      '#default_value' => implode(',', $current_ids),
      '#attributes' => [
        'class' => ['dam-widget__input'],
      ],
    ];

    // Selected media preview area.
    $element['selected'] = [
      '#type' => 'container',
      '#attributes' => [
        'class' => ['dam-widget__selected'],
      ],
    ];

    // Render current selections.
    foreach ($current_media as $media) {
      $element['selected'][$media->id()] = $this->buildMediaPreview($media);
    }

    // Actions area.
    $element['actions'] = [
      '#type' => 'container',
      '#attributes' => [
        'class' => ['dam-widget__actions'],
      ],
    ];

    $element['actions']['browse'] = [
      '#type' => 'button',
      '#value' => $is_multiple ? $this->t('Browse Media Library') : $this->t('Select Media'),
      '#attributes' => [
        'class' => ['dam-widget__browse', 'button'],
        'type' => 'button',
      ],
      '#limit_validation_errors' => [],
    ];

    if (!empty($current_ids)) {
      $element['actions']['clear'] = [
        '#type' => 'button',
        '#value' => $this->t('Clear'),
        '#attributes' => [
          'class' => ['dam-widget__clear', 'button', 'button--danger'],
          'type' => 'button',
        ],
        '#limit_validation_errors' => [],
      ];
    }

    // Settings for JavaScript.
    // Use field's allowed bundles from handler settings (field configuration).
    // This respects the "Reference type" settings on the field.
    $element['#attached']['drupalSettings']['damWidget'][$field_name] = [
      'fieldName' => $field_name,
      'cardinality' => $cardinality,
      'allowedBundles' => array_values($field_allowed_bundles),
    ];

    return $element;
  }

  /**
   * Build a preview for a media entity (grid-style like DAM).
   */
  protected function buildMediaPreview(Media $media) {
    $bundle = $media->bundle();
    $thumbnail_uri = NULL;

    // Try to get thumbnail.
    if ($media->hasField('thumbnail') && !$media->get('thumbnail')->isEmpty()) {
      $thumbnail = $media->get('thumbnail')->entity;
      if ($thumbnail) {
        $thumbnail_uri = $thumbnail->getFileUri();
      }
    }

    // Get bundle label.
    $bundle_entity = $this->entityTypeManager->getStorage('media_type')->load($bundle);
    $bundle_label = $bundle_entity ? $bundle_entity->label() : $bundle;

    // Get icon based on bundle.
    $icons = [
      'image' => '🖼️',
      'video' => '🎬',
      'audio' => '🎵',
      'document' => '📄',
      'file' => '📎',
      'remote_video' => '🎬',
    ];
    $icon = $icons[$bundle] ?? '📄';

    // Build item using inline markup to avoid Drupal's container
    // wrapping issues.
    $thumbnail_html = '';
    if ($thumbnail_uri) {
      $thumbnail_render = [
        '#theme' => 'image_style',
        '#style_name' => 'thumbnail',
        '#uri' => $thumbnail_uri,
        '#alt' => $media->label(),
        '#attributes' => [
          'class' => ['dam-widget__thumbnail'],
        ],
      ];
      $thumbnail_html = $this->renderer->render($thumbnail_render);
    }
    else {
      $thumbnail_html = '<span class="dam-widget__icon">' . $icon . '</span>';
    }

    $remove_label = $this->t('Remove');
    $name = htmlspecialchars($media->label());
    $meta = htmlspecialchars($bundle_label);

    $build = [
      '#markup' => '<div class="dam-widget__item" data-media-id="' . $media->id() . '">'
      . '<div class="dam-widget__thumb-wrapper">'
      . $thumbnail_html
      . '</div>'
      . '<button type="button" class="dam-widget__remove" aria-label="' . $remove_label . '">×</button>'
      . '<div class="dam-widget__info">'
      . '<span class="dam-widget__name" title="' . $name . '">' . $name . '</span>'
      . '<span class="dam-widget__meta">' . $meta . '</span>'
      . '</div>'
      . '</div>',
    ];

    return $build;
  }

  /**
   * {@inheritdoc}
   */
  public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
    $new_values = [];

    // Get the target_ids from the hidden field.
    if (!empty($values['target_ids'])) {
      $ids = array_filter(explode(',', $values['target_ids']));
      foreach ($ids as $delta => $id) {
        $new_values[$delta] = ['target_id' => $id];
      }
    }

    return $new_values;
  }

}
