<?php

namespace Drupal\languagewire_translation_provider\Settings;

use Drupal\languagewire_translation_provider\Date;
use Drupal\languagewire_translation_provider\LanguageWireConnector;
use function array_key_exists;
use function intval;
use function strlen;
use function substr;

/**
 * Job Settings.
 *
 * @codeCoverageIgnore
 */
final class JobSettings {
  /**
   * Service prefix.
   */
  public const SERVICE_PREFIX = 'service_';

  /**
   * Project template prefix.
   */
  public const PROJECT_TEMPLATE_PREFIX = 'template_';

  /**
   * Settings.
   *
   * @var array
   */
  private array $settings;

  /**
   * Constructs a new JobSettings object.
   *
   * @param array $settings
   *   Settings.
   */
  public function __construct(array $settings) {
    $this->settings = $settings;
  }

  /**
   * Get service.
   */
  public function getService(): ?int {
    return $this->getPrefixedFieldWithFallback(self::SERVICE_PREFIX, 'service');
  }

  /**
   * Get project template.
   *
   * @todo rename to getProjectTemplatePlatformId()
   */
  public function getProjectTemplate(): ?int {
    return $this->getPrefixedFieldWithFallback(self::PROJECT_TEMPLATE_PREFIX, 'project_template');
  }

  /**
   * Get user.
   */
  public function getUser(): ?int {
    return $this->getInt('user');
  }

  /**
   * Get work area.
   */
  public function getWorkArea(): ?int {
    return $this->getInt('work_area');
  }

  /**
   * Get translation memory.
   */
  public function getTranslationMemory(): ?int {
    return $this->getInt('translation_memory');
  }

  /**
   * Get term base.
   */
  public function getTermBase(): ?int {
    return $this->getInt('term_base');
  }

  /**
   * Get invoicing account.
   */
  public function getInvoicingAccount(): ?int {
    return $this->getInt('invoicing_account');
  }

  /**
   * Get order type.
   */
  public function getOrderType(): ?string {
    return $this->getString('order_type');
  }

  /**
   * Get deadline.
   */
  public function getDeadline(): ?string {
    return $this->getString('deadline');
  }

  /**
   * Get briefing.
   */
  public function getBriefing(): ?string {
    $briefing = $this->get('briefing');

    if ($briefing != NULL && is_array($briefing) && array_key_exists('value', $briefing)) {
      return $briefing['value'];
    }

    // Handle briefings stored prior to version 9.2.1.
    if ($briefing != NULL && is_string($briefing)) {
      return $briefing;
    }

    return NULL;
  }

  /**
   * Get deadline as date.
   */
  public function getDeadlineAsDate(): Date {
    $deadline = \DateTimeImmutable::createFromFormat(
      LanguageWireConnector::DEADLINE_DATE_FORMAT,
      $this->getDeadline(),
      new \DateTimeZone('UTC')
    );
    return new Date($deadline);
  }

  /**
   * Check if it is a bundling.
   */
  public function isBundling(): bool {
    return ((int) $this->get('bundling')) === 1;
  }

  /**
   * Get int.
   */
  public function getInt(string $key): ?int {
    $value = $this->get($key);
    return $value === NULL ? NULL : (int) $value;
  }

  /**
   * Get string.
   */
  public function getString(string $key): ?string {
    $value = $this->get($key);
    return $value === NULL ? NULL : (string) $value;
  }

  /**
   * Is item content enabled for translation.
   */
  public function isItemContentEnabledForTranslation(int $itemId, string $contentId): bool {
    return !isset($this->settings['content_settings']["item-$itemId"]["content-$contentId"])
      || $this->settings['content_settings']["item-$itemId"]["content-$contentId"];
  }

  /**
   * Get.
   */
  private function get(string $key) {
    return array_key_exists($key, $this->settings) ? $this->settings[$key] : NULL;
  }

  /**
   * Get prefixed field with fallback.
   */
  private function getPrefixedFieldWithFallback(string $prefix, string $fallbackSetting): ?int {
    $combinedTemplateService = $this->get('template_or_service');

    if ($combinedTemplateService == NULL) {
      return $this->get($fallbackSetting);
    }

    if (!str_contains($combinedTemplateService, $prefix)) {
      return NULL;
    }

    $parsedId = substr($combinedTemplateService, strlen($prefix));

    return intval($parsedId);
  }

}
