<?php

namespace Drupal\nodehive_dam\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\File\FileUrlGeneratorInterface;
use Drupal\Core\Render\RendererInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
 * Controller for the DAM widget endpoints.
 */
class DamWidgetController extends ControllerBase {

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

  /**
   * The file URL generator.
   *
   * @var \Drupal\Core\File\FileUrlGeneratorInterface
   */
  protected $fileUrlGenerator;

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

  /**
   * Constructs a DamWidgetController object.
   */
  public function __construct(
    EntityTypeManagerInterface $entity_type_manager,
    FileUrlGeneratorInterface $file_url_generator,
    RendererInterface $renderer,
  ) {
    $this->entityTypeManager = $entity_type_manager;
    $this->fileUrlGenerator = $file_url_generator;
    $this->renderer = $renderer;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_type.manager'),
      $container->get('file_url_generator'),
      $container->get('renderer')
    );
  }

  /**
   * Returns the modal HTML.
   */
  public function modal(): Response {
    $build = [
      '#theme' => 'dam_widget_modal',
    ];

    $html = $this->renderer->renderRoot($build);

    return new Response($html, 200, ['Content-Type' => 'text/html']);
  }

  /**
   * Returns filters (folders, collections, media types) as JSON.
   */
  public function filters(Request $request): JsonResponse {
    // Get allowed bundles from request (from field configuration).
    $bundles_param = $request->query->get('bundles', '');
    $allowed_bundles = array_filter(explode(',', $bundles_param));

    $data = [
      'folders' => [],
      'collections' => [],
      'media_types' => [],
    ];

    // Load folders.
    $folder_storage = $this->entityTypeManager->getStorage('taxonomy_term');
    $folder_tree = $folder_storage->loadTree('nodehive_dam_folder', 0, NULL, TRUE);

    foreach ($folder_tree as $term) {
      $data['folders'][] = [
        'id' => $term->id(),
        'name' => $term->getName(),
        'depth' => $term->depth ?? 0,
      ];
    }

    // Load collections.
    $collection_terms = $folder_storage->loadByProperties([
      'vid' => 'nodehive_dam_collection',
    ]);

    foreach ($collection_terms as $term) {
      $data['collections'][] = [
        'id' => $term->id(),
        'name' => $term->getName(),
      ];
    }

    // Load media types - filter by allowed bundles if specified.
    $media_types = $this->entityTypeManager->getStorage('media_type')->loadMultiple();
    foreach ($media_types as $type) {
      // If allowed bundles are specified, only include those.
      if (!empty($allowed_bundles) && !in_array($type->id(), $allowed_bundles)) {
        continue;
      }
      $data['media_types'][$type->id()] = $type->label();
    }

    return new JsonResponse($data);
  }

  /**
   * Returns media grid items as JSON.
   */
  public function grid(Request $request): JsonResponse {
    $search = $request->query->get('search', '');
    $type = $request->query->get('type', '');
    $folder = $request->query->get('folder', '');
    $collection = $request->query->get('collection', '');
    $bundles_param = $request->query->get('bundles', '');
    $allowed_bundles = array_filter(explode(',', $bundles_param));

    $media_storage = $this->entityTypeManager->getStorage('media');
    $query = $media_storage->getQuery()
      ->accessCheck(TRUE)
      ->sort('created', 'DESC')
      ->range(0, 100);

    // Search filter.
    if (!empty($search)) {
      $query->condition('name', $search, 'CONTAINS');
    }

    // Type filter (single type selected by user).
    if (!empty($type)) {
      $query->condition('bundle', $type);
    }
    // Allowed bundles filter (from field configuration).
    elseif (!empty($allowed_bundles)) {
      $query->condition('bundle', $allowed_bundles, 'IN');
    }

    // Folder filter.
    if ($folder === '_none') {
      $query->notExists('nodehive_dam_folder');
    }
    elseif (!empty($folder)) {
      $query->condition('nodehive_dam_folder', $folder);
    }

    // Collection filter.
    if (!empty($collection)) {
      $query->condition('nodehive_dam_collections', $collection);
    }

    $ids = $query->execute();
    $items = [];

    if (!empty($ids)) {
      $media_entities = $media_storage->loadMultiple($ids);

      foreach ($media_entities as $media) {
        $item = [
          'id' => (int) $media->id(),
          'name' => $media->label(),
          'bundle' => $media->bundle(),
          'thumbnail' => NULL,
        ];

        // Get thumbnail URL.
        if ($media->hasField('thumbnail') && !$media->get('thumbnail')->isEmpty()) {
          $thumbnail = $media->get('thumbnail')->entity;
          if ($thumbnail) {
            $style = $this->entityTypeManager->getStorage('image_style')->load('medium');
            if ($style) {
              $item['thumbnail'] = $style->buildUrl($thumbnail->getFileUri());
            }
            else {
              $item['thumbnail'] = $this->fileUrlGenerator->generateAbsoluteString($thumbnail->getFileUri());
            }
          }
        }

        $items[] = $item;
      }
    }

    return new JsonResponse(['items' => $items]);
  }

  /**
   * Returns preview data for selected media items.
   */
  public function preview(Request $request): JsonResponse {
    $ids_param = $request->query->get('ids', '');
    $ids = array_filter(explode(',', $ids_param));
    $items = [];

    if (!empty($ids)) {
      $media_storage = $this->entityTypeManager->getStorage('media');
      $media_entities = $media_storage->loadMultiple($ids);

      // Load media types for labels.
      $media_types = $this->entityTypeManager->getStorage('media_type')->loadMultiple();

      // Preserve order from IDs.
      foreach ($ids as $id) {
        if (!isset($media_entities[$id])) {
          continue;
        }

        $media = $media_entities[$id];
        $bundle = $media->bundle();
        $bundle_label = isset($media_types[$bundle]) ? $media_types[$bundle]->label() : $bundle;

        $item = [
          'id' => (int) $media->id(),
          'name' => $media->label(),
          'bundle' => $bundle,
          'bundle_label' => $bundle_label,
          'thumbnail' => NULL,
        ];

        // Get thumbnail URL.
        if ($media->hasField('thumbnail') && !$media->get('thumbnail')->isEmpty()) {
          $thumbnail = $media->get('thumbnail')->entity;
          if ($thumbnail) {
            $style = $this->entityTypeManager->getStorage('image_style')->load('thumbnail');
            if ($style) {
              $item['thumbnail'] = $style->buildUrl($thumbnail->getFileUri());
            }
            else {
              $item['thumbnail'] = $this->fileUrlGenerator->generateAbsoluteString($thumbnail->getFileUri());
            }
          }
        }

        $items[] = $item;
      }
    }

    return new JsonResponse(['items' => $items]);
  }

}
