<?php

declare(strict_types=1);

namespace Drupal\languagewire_translation_provider\Cron\Job;

use Drupal\languagewire_translation_provider\Adapter\SystemInterface;
use Drupal\languagewire_translation_provider\Client\LanguageWireClientFactory;
use Drupal\languagewire_translation_provider\Database\ProjectRepositoryInterface;
use Drupal\languagewire_translation_provider\Domain\Project;
use Drupal\languagewire_translation_provider\Domain\ProjectStatus;
use Drupal\languagewire_translation_provider\Service\ProjectContentUploader;

/**
 * Content Upload Job.
 */
final class ContentUploadJob extends BaseJob {

  /**
   * Content uploader.
   *
   * @var \Drupal\languagewire_translation_provider\Service\ProjectContentUploader
   */
  private ProjectContentUploader $contentUploader;

  /**
   * Constructs a new ContentUploadJob object.
   *
   * @param \Drupal\languagewire_translation_provider\Adapter\SystemInterface $system
   *   System.
   * @param \Drupal\languagewire_translation_provider\Service\ProjectContentUploader $contentUploader
   *   Content uploader.
   * @param \Drupal\languagewire_translation_provider\Client\LanguageWireClientFactory $clientFactory
   *   LanguageWire client factory.
   * @param \Drupal\languagewire_translation_provider\Database\ProjectRepositoryInterface $projectRepository
   *   Project repository.
   */
  public function __construct(
    SystemInterface $system,
    ProjectContentUploader $contentUploader,
    LanguageWireClientFactory $clientFactory,
    ProjectRepositoryInterface $projectRepository
  ) {
    parent::__construct($system, $projectRepository, $clientFactory);
    $this->contentUploader = $contentUploader;
  }

  /**
   * Job name.
   */
  protected function jobName(): string {
    return "Content Upload";
  }

  /**
   * Get projects.
   *
   * @return \Drupal\languagewire_translation_provider\Domain\Project[]
   *   Projects.
   */
  protected function getProjects(): array {
    return $this->projectRepository->getAllByStatus(ProjectStatus::uploading());
  }

  /**
   * Process project.
   *
   * @throws \Drupal\languagewire_translation_provider\Client\RecoverableException
   * @throws \Drupal\languagewire_translation_provider\api\Core\Exception\Error
   */
  protected function processProject(Project $project): void {
    $this->contentUploader->uploadProjectContent(
          $project,
          $project->getDocuments(),
          $project->getTmgmtJob(),
          $this->getLanguageWireClient($project->getTmgmtJob()),
          !$project->hasBundlingId() || $this->getLastBundle($project->getBundlingId())->getId() === $project->getId()
      );
    $this->projectRepository->save($project);
  }

  /**
   * Fetch last bundle.
   */
  private function getLastBundle(string $bundleId): Project {
    $allBundles = $this->projectRepository->getAllByBundlingId($bundleId);
    return end($allBundles);
  }

}
