<?php

declare(strict_types=1);

namespace Drupal\sobki_assets\HookHandler;

use Drupal\Core\Cache\Cache;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\File\FileUrlGeneratorInterface;
use Drupal\Core\Theme\ThemeManagerInterface;
use Drupal\sobki_assets\Form\AssetsUploadForm;
use Drupal\sobki_assets\Service\DestinationDirectoryPurgerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Page attachments hook handler.
 */
class PageAttachments implements ContainerInjectionInterface {

  public function __construct(
    protected ThemeManagerInterface $themeManager,
    protected ConfigFactoryInterface $configFactory,
    protected FileUrlGeneratorInterface $fileUrlGenerator,
    protected EntityTypeManagerInterface $entityTypeManager,
    protected FileSystemInterface $fileSystem,
  ) {}

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

  /**
   * Main hook_page_attachments handler method.
   *
   * @param array $attachments
   *   Attachments render array.
   */
  public function attach(array &$attachments): void {
    $active_theme = $this->themeManager->getActiveTheme()->getName();
    $front_theme = $this->configFactory->get('system.theme')->get('default');
    if ($active_theme !== $front_theme || !\file_exists(AssetsUploadForm::DESTINATION_DIRECTORY)) {
      return;
    }

    $destination = $this->fileUrlGenerator->generateString(AssetsUploadForm::DESTINATION_DIRECTORY);
    $files = $this->fileSystem->scanDirectory(AssetsUploadForm::DESTINATION_DIRECTORY, '/\.css/');
    foreach ($files as $file) {
      $attachments['#attached']['html_head'][] = [
        [
          '#tag' => 'link',
          '#attributes' => [
            'rel' => 'stylesheet',
            'href' => $destination . '/' . $file->filename,
          ],
        ],
        'sobki_assets_css_' . $file->filename,
      ];
    }
    $cacheTags = $this->getAssetsCacheTags();
    $attachments['#cache']['tags'] = Cache::mergeTags(
      $attachments['#cache']['tags'] ?? [],
      [...$cacheTags, DestinationDirectoryPurgerInterface::ASSETS_CACHE_TAG]
    );
  }

  /**
   * Get cache tags.
   *
   * @return array
   *   An array of cache tags.
   */
  protected function getAssetsCacheTags(): array {
    $fileStorage = $this->entityTypeManager->getStorage('file');
    $query = $fileStorage->getQuery()
      ->accessCheck(FALSE)
      ->condition('uri', AssetsUploadForm::DESTINATION_DIRECTORY . '/%', 'LIKE');

    $fids = $query->execute();

    return \array_map(static fn ($fid) => 'file:' . $fid, $fids);
  }

}
