<?php

declare(strict_types=1);

namespace Drupal\languagewire_translation_provider\Service;

use Drupal\languagewire_translation_provider\Adapter\TMGMT\TmgmtJobInterface;
use Drupal\languagewire_translation_provider\Database\ProjectRepositoryInterface;
use Drupal\languagewire_translation_provider\Domain\DocumentStatus;
use Drupal\languagewire_translation_provider\Domain\ProjectStatus;

/**
 * Project State Handler.
 */
class ProjectStateHandler {

  /**
   * Project repository.
   *
   * @var \Drupal\languagewire_translation_provider\Database\ProjectRepositoryInterface
   */
  private ProjectRepositoryInterface $projectRepository;

  const REIMPORT_MESSAGE = 'Project has been manually reimported by an administrator.';

  /**
   * Constructs a new ProjectStateHandler object.
   *
   * @param \Drupal\languagewire_translation_provider\Database\ProjectRepositoryInterface $projectRepository
   *   Project repository.
   */
  public function __construct(ProjectRepositoryInterface $projectRepository) {
    $this->projectRepository = $projectRepository;
  }

  /**
   * Set project to error state.
   *
   * @todo use this when cron jobs fail with Tmgmt jobs
   */
  public function setJobToErrorState(TmgmtJobInterface $job, string $jobErrorMessage): void {
    $projects = $this->projectRepository->getAllByTmgmtJobId($job->jobId());

    foreach ($projects as $project) {
      $project->setStatus(ProjectStatus::error());
      $this->projectRepository->save($project);
    }

    $job->addMessage($jobErrorMessage);
  }

  /**
   * Set project to in progress state.
   */
  public function setJobToInProgressState(TmgmtJobInterface $job): void {
    $projects = $this->projectRepository->getAllByTmgmtJobId($job->jobId());

    $shouldActivateTmgmtJob = FALSE;

    foreach ($projects as $project) {
      if ($project->canBeReimported()) {
        $project->setStatus(ProjectStatus::inProgress());
        $project->updateAllDocumentsStatus(DocumentStatus::uploadedContent());

        $this->projectRepository->save($project);
        $shouldActivateTmgmtJob = TRUE;
      }
    }

    if ($shouldActivateTmgmtJob) {
      $this->reactivateTmgmtJob($job);
    }
  }

  /**
   * Try cancelling job projects.
   */
  public function tryCancellingJobProjects(TmgmtJobInterface $job): bool {
    $projects = $this->projectRepository->getAllByTmgmtJobId($job->jobId());

    foreach ($projects as $project) {
      if (!$project->getStatus()->isCancellable()) {
        return FALSE;
      }

      $project->setStatus(ProjectStatus::cancelled());
      $this->projectRepository->save($project);
    }

    return TRUE;
  }

  /**
   * Reactivate TMGMT job.
   */
  private function reactivateTmgmtJob(TmgmtJobInterface $job): void {
    $job->makeActive();
    $job->makeItemsActive();
    $job->addMessage(self::REIMPORT_MESSAGE);
    $job->save();
  }

}
