<?php

namespace Drupal\languagewire_translation_provider\Adapter\TMGMT;

use Drupal\languagewire_translation_provider\Adapter\SystemInterface;
use Drupal\tmgmt\TranslatorInterface;

/**
 * Adapter on TMGMT translator.
* */
final class TmgmtTranslator implements TmgmtTranslatorInterface {

  /**
   * Translator.
   *
   * @var \Drupal\tmgmt\TranslatorInterface
   */
  private TranslatorInterface $translator;

  /**
   * Default item upload batch size.
   */
  private const DEFAULT_ITEM_UPLOAD_BATCH_SIZE = 20;

  /**
   * Default HTML preview enabled.
   */
  private const DEFAULT_HTML_PREVIEW_ENABLED = TRUE;

  /**
   * Constructs a new TmgmtTranslator object.
   *
   * @param \Drupal\tmgmt\TranslatorInterface $translator
   *   Translator.
   */
  public function __construct(TranslatorInterface $translator) {
    $this->translator = $translator;
  }

  /**
   * Get translator ID.
   */
  public function id(): ?string {
    return $this->translator->id();
  }

  /**
   * Get client ID.
   */
  public function getClientId(): string {
    return $this->translator->getSetting('client_id') ?: '';
  }

  /**
   * Get client secret.
   */
  public function getClientSecret(): string {
    return $this->translator->getSetting('client_secret') ?: '';
  }

  /**
   * Has credentials.
   */
  public function hasCredentials(): bool {
    return !empty($this->getClientId()) && !empty($this->getClientSecret());
  }

  /**
   * Get mapped remote language.
   */
  public function mapToRemoteLanguage(string $language): string {
    return $this->translator->mapToRemoteLanguage($language);
  }

  /**
   * Get remote languages mappings.
   */
  public function getRemoteLanguagesMappings(): array {
    return $this->translator->getRemoteLanguagesMappings();
  }

  /**
   * Get selected services.
   */
  public function getSelectedServices(): array {
    return $this->parseSettings($this->translator->getSetting('services') ?: []);
  }

  /**
   * Has services.
   */
  public function hasServices(): bool {
    return count($this->getSelectedServices()) > 0;
  }

  /**
   * Get selected user.
   */
  public function getSelectedUser(): array {
    return $this->parseSettings($this->translator->getSetting('user') ?: []);
  }

  /**
   * Has user.
   */
  public function hasUser(): bool {
    return count($this->getSelectedUser()) > 0;
  }

  /**
   * Get selected translation memories.
   */
  public function getSelectedTranslationMemories(): array {
    return $this->parseSettings($this->translator->getSetting('translation_memories') ?: []);
  }

  /**
   * Has translation memories.
   */
  public function hasTranslationMemories(): bool {
    return count($this->getSelectedTranslationMemories()) > 0;
  }

  /**
   * Get selected term bases.
   */
  public function getSelectedTermBases(): array {
    return $this->parseSettings($this->translator->getSetting('term_bases') ?: []);
  }

  /**
   * Has term bases.
   */
  public function hasTermBases(): bool {
    return count($this->getSelectedTermBases()) > 0;
  }

  /**
   * Get selected work areas.
   */
  public function getSelectedWorkAreas(): array {
    return $this->parseSettings($this->translator->getSetting('work_areas') ?: []);
  }

  /**
   * Has work areas.
   */
  public function hasWorkAreas(): bool {
    return count($this->getSelectedWorkAreas()) > 0;
  }

  /**
   * Get selected invoicing accounts.
   */
  public function getSelectedInvoicingAccounts(): array {
    return $this->parseSettings($this->translator->getSetting('invoicing_accounts') ?: []);
  }

  /**
   * Has invoicing accounts.
   */
  public function hasInvoicingAccounts(): bool {
    return count($this->getSelectedInvoicingAccounts()) > 0;
  }

  /**
   * Get selected order type.
   */
  public function getSelectedOrderTypes(): array {
    return $this->parseSettings($this->translator->getSetting('order_types') ?: []);
  }

  /**
   * Has order type.
   */
  public function hasOrderTypes(): bool {
    return count($this->getSelectedOrderTypes()) > 0;
  }

  /**
   * Get selected project template IDs.
   */
  public function getSelectedProjectTemplateIds(): array {
    return $this->parseSettings($this->translator->getSetting('project_templates') ?: []);
  }

  /**
   * Has project templates.
   */
  public function hasProjectTemplates(): bool {
    return count($this->getSelectedProjectTemplateIds()) > 0;
  }

  /**
   * Is bundle languages enabled.
   */
  public function isBundlingEnabled(): bool {
    return (bool) $this->translator->getSetting('bundling');
  }

  /**
   * Is default delivery date enabled.
   */
  public function isDefaultDeliveryDateEnabled(): bool {
    return (bool) $this->translator->getSetting('default_delivery_date');
  }

  /**
   * Is html preview enabled.
   */
  public function isHtmlPreviewEnabled(): bool {
    return (bool) ($this->translator->getSetting('html_preview') ?? TmgmtTranslator::DEFAULT_HTML_PREVIEW_ENABLED);
  }

  /**
   * Get item upload batch size.
   */
  public function getItemUploadBatchSize(): int {
    return $this->translator->getSetting('item_upload_batch_size')
            ?: TmgmtTranslator::DEFAULT_ITEM_UPLOAD_BATCH_SIZE;
  }

  /**
   * Clear selected configuration items.
   */
  public function clearSelectedConfigurationItems(): void {
    $this->translator->setSetting('services', NULL);
    $this->translator->setSetting('translation_memories', NULL);
    $this->translator->setSetting('term_bases', NULL);
    $this->translator->setSetting('work_areas', NULL);
    $this->translator->setSetting('invoicing_accounts', NULL);
    $this->translator->setSetting('order_types', NULL);
    $this->translator->setSetting('project_templates', NULL);
  }

  /**
   * Is configured.
   */
  public function isConfigured(): bool {
    return $this->hasCredentials()
            && $this->hasInvoicingAccounts()
            && $this->hasServices()
            && $this->hasTranslationMemories()
            && $this->hasWorkAreas()
            && $this->hasLimitsDefined();
  }

  /**
   * Get plugin configuration.
   */
  public function getPluginConfiguration(SystemInterface $system): TranslatorPluginConfiguration {
    return new TranslatorPluginConfiguration($system, $this);
  }

  /**
   * Set max documents per project.
   */
  public function setMaxDocumentsPerProject(int $value): void {
    $this->translator->setSetting('max_documents_per_project', $value);
  }

  /**
   * Get max documents per project.
   */
  public function getMaxDocumentsPerProject(): int {
    return $this->translator->getSetting('max_documents_per_project') ?? 0;
  }

  /**
   * Check if there is limits defined for projects.
   */
  private function hasLimitsDefined(): bool {
    return $this->getMaxDocumentsPerProject() > 0;
  }

  /**
   * Parse settings.
   */
  private function parseSettings(string|array $settings): array {
    if (empty($settings)) {
      return [];
    }

    return is_string($settings) ? [$settings] : $settings;
  }

}
