<?php

declare(strict_types=1);

namespace Drupal\languagewire_translation_provider\Adapter\PreviewSite;

use Drupal\languagewire_translation_provider\Adapter\Entity\EntityInterface;
use Drupal\languagewire_translation_provider\Domain\Document;

/**
 * Preview site build factory.
 */
final class PreviewSiteBuildFactory {

  public const MAX_TITLE_LENGTH = 28; // 32 characters minus 4 for the udf extension name.

  private const BUILD_LABEL = 'LanguageWire HTML Preview';

  private const STRATEGY_LABEL = "LanguageWire HTML Preview Strategy (%s)";

  /**
   * Site build repository.
   *
   * @var PreviewSiteBuildRepositoryInterface
   */
  private PreviewSiteBuildRepositoryInterface $siteBuildRepository;

  /**
   * Strategy repository.
   *
   * @var PreviewStrategyRepositoryInterface
   */
  private PreviewStrategyRepositoryInterface $strategyRepository;

  /**
   * Constructs a new PreviewSiteBuildFactory object.
   *
   * @param PreviewSiteBuildRepositoryInterface $siteBuildRepository
   *   Site build repository.
   * @param PreviewStrategyRepositoryInterface $strategyRepository
   *   Strategy repository.
   */
  public function __construct(PreviewSiteBuildRepositoryInterface $siteBuildRepository, PreviewStrategyRepositoryInterface $strategyRepository) {
    $this->siteBuildRepository = $siteBuildRepository;
    $this->strategyRepository = $strategyRepository;
  }

  /**
   * Create site build.
   */
  public function createSiteBuild(EntityInterface $entity, Document $document, int $jobID): ?PreviewSiteBuild {
    $strategy = $this->createStrategyForEntity($entity->getEntityId(), $document, $jobID);
    return $this->siteBuildRepository->create($entity, self::BUILD_LABEL, $strategy->getId());
  }

  /**
   * Create strategy for entity.
   */
  private function createStrategyForEntity(string $contentId, Document $document, int $jobID): PreviewStrategy {
    $documentNameAppend = '_' . $jobID . '_' . substr(md5(json_encode($document->getTmgmtItem()->getRawData())), 0, 5);

    $maxTitleLength = self::MAX_TITLE_LENGTH - strlen($documentNameAppend);
    $title = mb_substr(trim($document->getTitle()), 0, $maxTitleLength);

    if (preg_match('/[^\p{Latin}\s\p{P}\p{N}]/u', $title)) {
      $title = rtrim(base64_encode(substr($title, 0, intval(ceil($maxTitleLength * 3 / 4)))), '=');
    }

    $fileName = $title . $documentNameAppend;
    $contentTimeSuffix = sprintf("%s_%d", $contentId, time());
    return $this->strategyRepository->create(
      $fileName,
      sprintf(self::STRATEGY_LABEL, $contentTimeSuffix),
      $fileName
    );
  }

}
