<?php

declare(strict_types=1);

namespace Drupal\languagewire_translation_provider\Adapter\TMGMT;

use Drupal\languagewire_translation_provider\Adapter\SystemInterface;
use Drupal\languagewire_translation_provider\Client\ConfigurationItemInterface;
use Drupal\languagewire_translation_provider\Domain\ProjectTemplate;
use function array_reduce;

/**
 * Translator Plugin Configuration.
* */
final class TranslatorPluginConfiguration {

  /**
   * Drupal adapter.
   *
   * @var \Drupal\languagewire_translation_provider\Adapter\SystemInterface
   *   Drupal adapter.
   */
  private SystemInterface $drupal;

  /**
   * Translator.
   *
   * @var TmgmtTranslatorInterface
   *   Translator.
   */
  private TmgmtTranslatorInterface $translator;

  /**
   * Constructs a new TranslatorPluginConfiguration object.
   *
   * @param \Drupal\languagewire_translation_provider\Adapter\SystemInterface $drupal
   *   Drupal adapter.
   * @param TmgmtTranslatorInterface $translator
   *   Translator.
   */
  public function __construct(SystemInterface $drupal, TmgmtTranslatorInterface $translator) {
    $this->drupal = $drupal;
    $this->translator = $translator;
  }

  /**
   * Is fully initialized.
   */
  public function isFullyInitialized(): bool {
    return $this->translator->hasCredentials()
      && !empty($this->getAvailableServices())
      && !empty($this->getAvailableWorkAreas())
      && !empty($this->getAvailableInvoicingAccounts())
      && !empty($this->getAvailableTranslationMemories())
      && !empty($this->getAvailableTermBases());
  }

  /**
   * Get available services.
   */
  public function getAvailableServices(): array {
    return $this->drupal->serviceRepository()->getAll($this->translator);
  }

  /**
   * Get available services flat.
   */
  public function getAvailableServicesFlat(): array {
    return $this->reduceToKeyValuePairs($this->getAvailableServices());
  }

  /**
   * Get available project templates.
   */
  public function getAvailableProjectTemplates(): array {
    return $this->drupal->projectTemplateRepository()->getAll($this->translator);
  }

  /**
   * Get available project templates flat.
   */
  public function getAvailableProjectTemplatesFlat(): array {
    return array_reduce($this->getAvailableProjectTemplates(), function (array $result, ProjectTemplate $item): array {
      $result[$item->getPlatformId()] = $item->getName();
      return $result;
    }, []);
  }

  /**
   * Get available translation memories.
   */
  public function getAvailableTranslationMemories(): array {
    return $this->drupal->translationMemoryRepository()->getAll($this->translator);
  }

  /**
   * Get available translation memories flat.
   */
  public function getAvailableTranslationMemoriesFlat(): array {
    return $this->reduceToKeyValuePairs($this->getAvailableTranslationMemories());
  }

  /**
   * Get available term bases.
   */
  public function getAvailableTermBases(): array {
    return $this->drupal->termBaseRepository()->getAll($this->translator);
  }

  /**
   * Get available term bases flat.
   */
  public function getAvailableTermBasesFlat(): array {
    return $this->reduceToKeyValuePairs($this->getAvailableTermBases());
  }

  /**
   * Get available invoicing accounts.
   */
  public function getAvailableInvoicingAccounts(): array {
    return $this->drupal->invoicingAccountRepository()->getAll($this->translator);
  }

  /**
   * Get available invoicing accounts flat.
   */
  public function getAvailableInvoicingAccountsFlat(): array {
    return $this->reduceToKeyValuePairs($this->getAvailableInvoicingAccounts());
  }

  /**
   * Get available work areas.
   */
  public function getAvailableWorkAreas(): array {
    return $this->drupal->workAreaRepository()->getAll($this->translator);
  }

  /**
   * Get available work areas flat.
   */
  public function getAvailableWorkAreasFlat(): array {
    return $this->reduceToKeyValuePairs($this->getAvailableWorkAreas());
  }

  /**
   * Get available users.
   */
  public function getAvailableUsers(): array {
    return $this->drupal->userRepository()->getAll($this->translator);
  }

  /**
   * Get available users flat.
   */
  public function getAvailableUsersFlat(): array {
    return $this->reduceToKeyValuePairs($this->getAvailableUsers());
  }

  /**
   * Reduce to key value pairs.
   */
  private function reduceToKeyValuePairs(array $items): array {
    return array_reduce($items, function (array $result, ConfigurationItemInterface $item): array {
      $result[$item->id()] = $item->name();
      return $result;
    }, []);
  }

}
