<?php

namespace Drupal\languagewire_translation_provider\Platform\Document;

use Drupal\languagewire_translation_provider\Adapter\SystemInterface;
use Drupal\languagewire_translation_provider\api\Libraries\Content\Udf\Frame;
use Drupal\languagewire_translation_provider\api\Libraries\Content\Udf\Metadata;
use Drupal\languagewire_translation_provider\api\Libraries\Content\Udf\UniversalDocument;
use Drupal\languagewire_translation_provider\api\Libraries\Content\UdfContent;
use Drupal\languagewire_translation_provider\api\Libraries\Document\DraftDocument;
use Drupal\languagewire_translation_provider\Content\TMGMTContent;
use Drupal\languagewire_translation_provider\Settings\JobSettings;

/**
 * UDF Document.
 */
final class UdfDocument {

  /**
   * Uploadable Document.
   *
   * @var UploadableDocument
   */
  private UploadableDocument $uploadableDocument;

  /**
   * Job Settings.
   *
   * @var \Drupal\languagewire_translation_provider\Settings\JobSettings
   */
  private JobSettings $jobSettings;

  /**
   * System.
   *
   * @var \Drupal\languagewire_translation_provider\Adapter\SystemInterface
   */
  private SystemInterface $system;

  /**
   * Constructs a new UdfDocument object.
   *
   * @param \Drupal\languagewire_translation_provider\Platform\Document\UploadableDocument $uploadableDocument
   *   Uploadable Document.
   * @param \Drupal\languagewire_translation_provider\Settings\JobSettings $jobSettings
   *   Job Settings.
   * @param \Drupal\languagewire_translation_provider\Adapter\SystemInterface $system
   *   System.
   */
  public function __construct(UploadableDocument $uploadableDocument, JobSettings $jobSettings, SystemInterface $system) {
    $this->uploadableDocument = $uploadableDocument;
    $this->jobSettings = $jobSettings;
    $this->system = $system;
  }

  /**
   * To Platform Draft Document.
   */
  public function toPlatformDraftDocument(): DraftDocument {
    return new DraftDocument(
          new UdfContent(
              new UniversalDocument($this->toFrames())
          ),
          $this->uploadableDocument->getLanguageMapping()->remoteLanguage(),
          $this->getNormalizedDocumentTitle()
      );
  }

  /**
   * Is Empty.
   */
  public function isEmpty(): bool {
    return count($this->toFrames()) == 0;
  }

  /**
   * To Frames.
   *
   * @return \Drupal\languagewire_translation_provider\api\Libraries\Content\Udf\Frame[]
   *   Frames.
   */
  private function toFrames(): array {

    $frames = [];

    foreach ($this->uploadableDocument->getContent() as $content) {
      if ($this->canTranslateContent($content)) {
        $frames[] = new Frame(
              $content->getText(),
              "'{$this->uploadableDocument->getTitle()}' item, '{$content->getLabel()}' field",
              new Metadata(['contentId' => $content->getContentId()])
          );
      }
    }

    return $frames;
  }

  /**
   * Can Translate Content.
   */
  private function canTranslateContent(TMGMTContent $content): bool {
    return $this->jobSettings->isItemContentEnabledForTranslation(
          $this->uploadableDocument->jobItemId(),
          $content->getSanitizedContentId()
      );
  }

  /**
   * Get Normalized Document Title.
   */
  private function getNormalizedDocumentTitle(): string {
    $itemTitle = $this->system->encodeString($this->uploadableDocument->getTitle());
    return $this->system->substring($itemTitle, 0, 100);
  }

}
