<?php

declare(strict_types=1);

namespace Drupal\languagewire_translation_provider\Domain;

use Drupal\languagewire_translation_provider\Settings\OrderType;

/**
 * Project template.
 */
final class ProjectTemplate implements \JsonSerializable {

  /**
   * Name.
   *
   * @var string
   */
  private string $name;

  /**
   * Platform ID.
   *
   * @var int
   */
  private int $platformId;

  /**
   * Target languages.
   *
   * @var array
   */
  private array $targetLanguages;

  /**
   * User ID.
   *
   * @var int
   */
  private int $userId;

  /**
   * Work area ID.
   *
   * @var int
   */
  private int $workAreaId;

  /**
   * Invoicing account ID.
   *
   * @var int
   */
  private int $invoicingAccountId;

  /**
   * Translation Memory ID.
   *
   * @var int|null
   */
  private ?int $translationMemoryId;

  /**
   * Term Base ID.
   *
   * @var int|null
   */
  private ?int $termBaseId;

  /**
   * Order type.
   *
   * @var string
   */
  private string $orderType;

  /**
   * Template ID.
   *
   * @var int|null
   */
  private ?int $templateId;

  /**
   * Description.
   *
   * @var string|null
   */
  private ?string $description;

  /**
   * Project name.
   *
   * @var string|null
   */
  private ?string $projectName;

  /**
   * Source language.
   *
   * @var string|null
   */
  private ?string $sourceLanguage;

  /**
   * Desired deadline.
   *
   * @var \DateTimeImmutable|null
   */
  private ?\DateTimeImmutable $desiredDeadline;

  /**
   * Available services.
   *
   * @var array|null
   */
  private ?array $availableServices;

  /**
   * Briefing to LanguageWire.
   *
   * @var string|null
   */
  private ?string $briefingToLanguageWire;

  /**
   * Constructs a new ProjectTemplate object.
   *
   * @param string $name
   *   Name.
   * @param int $platformId
   *   Platform ID.
   * @param array $targetLanguages
   *   Target languages.
   * @param int $userId
   *   User ID.
   * @param int $workAreaId
   *   Work area ID.
   * @param int $invoicingAccountId
   *   Invoicing account ID.
   * @param int|null $translationMemoryId
   *   Translation memory ID.
   * @param int|null $termBaseId
   *   Term base ID.
   * @param string $orderType
   *   Order type.
   * @param int|null $templateId
   *   Template ID.
   * @param string|null $description
   *   Description.
   * @param string|null $projectName
   *   Project name.
   * @param string|null $sourceLanguage
   *   Source language.
   * @param \DateTimeImmutable|null $desiredDeadline
   *   Desired deadline.
   * @param array|null $availableServices
   *   Available services.
   * @param string|null $briefingToLanguageWire
   *   Briefing to LanguageWire.
   */
  public function __construct(
    string $name,
    int $platformId,
    array $targetLanguages,
    int $userId,
    int $workAreaId,
    int $invoicingAccountId,
    ?int $translationMemoryId,
    ?int $termBaseId,
    string $orderType,
    ?int $templateId = NULL,
    ?string $description = NULL,
    ?string $projectName = NULL,
    ?string $sourceLanguage = NULL,
    ?\DateTimeImmutable $desiredDeadline = NULL,
    ?array $availableServices = NULL,
    ?string $briefingToLanguageWire = NULL
  ) {
    $this->name = $name;
    $this->platformId = $platformId;
    $this->targetLanguages = $targetLanguages;
    $this->userId = $userId;
    $this->workAreaId = $workAreaId;
    $this->invoicingAccountId = $invoicingAccountId;
    $this->translationMemoryId = $translationMemoryId;
    $this->termBaseId = $termBaseId;
    $this->orderType = $orderType;
    $this->templateId = $templateId;
    $this->description = $description;
    $this->projectName = $projectName;
    $this->sourceLanguage = $sourceLanguage;
    $this->desiredDeadline = $desiredDeadline;
    $this->availableServices = $availableServices;
    $this->briefingToLanguageWire = $briefingToLanguageWire;
  }

  /**
   * Get name.
   */
  public function getName(): string {
    return $this->name;
  }

  /**
   * Get platform ID.
   */
  public function getPlatformId(): int {
    return $this->platformId;
  }

  /**
   * Get target languages.
   */
  public function getTargetLanguages(): array {
    return $this->targetLanguages;
  }

  /**
   * Get user ID.
   */
  public function getUserId(): int {
    return $this->userId;
  }

  /**
   * Get work area ID.
   */
  public function getWorkAreaId(): int {
    return $this->workAreaId;
  }

  /**
   * Get invoicing account ID.
   */
  public function getInvoicingAccountId(): int {
    return $this->invoicingAccountId;
  }

  /**
   * Get translation memory ID.
   */
  public function getTranslationMemoryId(): ?int {
    return $this->translationMemoryId;
  }

  /**
   * Get term base ID.
   */
  public function getTermBaseId(): ?int {
    return $this->termBaseId;
  }

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

  /**
   * Get template ID.
   */
  public function getTemplateId(): ?int {
    return $this->templateId;
  }

  /**
   * Get description.
   */
  public function getDescription(): ?string {
    return $this->description;
  }

  /**
   * Get project name.
   */
  public function getProjectName(): ?string {
    return $this->projectName;
  }

  /**
   * Get source language.
   */
  public function getSourceLanguage(): ?string {
    return $this->sourceLanguage;
  }

  /**
   * Get desired deadline.
   */
  public function getDesiredDeadline(): ?\DateTimeImmutable {
    return $this->desiredDeadline;
  }

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

  /**
   * Get briefing to LanguageWire.
   */
  public function getBriefingToLanguageWire(): ?string {
    return $this->briefingToLanguageWire;
  }

  /**
   * From platform project template.
   *
   * @throws \DateMalformedStringException
   */
  public static function fromPlatformProjectTemplate(array $platformProjectTemplate): self {
    return new self(
      $platformProjectTemplate['name'],
      $platformProjectTemplate['id'],
      $platformProjectTemplate['targetLanguages'],
      $platformProjectTemplate['userId'] ?? 0,
      $platformProjectTemplate['workAreaId'],
      $platformProjectTemplate['invoicingAccountId'],
      $platformProjectTemplate['translationMemoryId'] ?? 0,
      $platformProjectTemplate['termBaseId'] ?? 0,
      $platformProjectTemplate['orderType'] ?? OrderType::ORDER,
      NULL,
      $platformProjectTemplate['description'],
      $platformProjectTemplate['projectName'],
      $platformProjectTemplate['sourceLanguage'],
      new \DateTimeImmutable($platformProjectTemplate['desiredDeadlineDate'] ?? 'now'),
      NULL,
      $platformProjectTemplate['briefingToLanguagewire'] ?? NULL
    );
  }

  /**
   * Implements JsonSerializable interface to allow \json_encode() usage.
   */
  public function jsonSerialize(): array {
    return get_object_vars($this);
  }

}
