<?php

declare(strict_types=1);

namespace Drupal\languagewire_translation_provider\Ui;

use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\languagewire_translation_provider\Adapter\TMGMT\TmgmtJobInterface;
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\LanguageWireConnector;

/**
 * Job Info UI.
 */
final class JobInfoUi {
  use StringTranslationTrait;

  /**
   * Module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  private ModuleHandlerInterface $moduleHandler;

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

  /**
   * Constructs a new JobInfoUi object.
   *
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler
   *   Module handler.
   * @param \Drupal\languagewire_translation_provider\Database\ProjectRepositoryInterface $projectRepository
   *   Project repository.
   */
  public function __construct(ModuleHandlerInterface $moduleHandler, ProjectRepositoryInterface $projectRepository) {
    $this->moduleHandler = $moduleHandler;
    $this->projectRepository = $projectRepository;
  }

  /**
   * Create job info form.
   *
   * @param \Drupal\languagewire_translation_provider\Adapter\TMGMT\TmgmtJobInterface $job
   *   TMGMT job.
   *
   * @return array
   *   Form.
   */
  public function createJobInfoForm(TmgmtJobInterface $job): array {
    $form = [];

    $projects = $this->projectRepository->getAllByTmgmtJobId($job->jobId());

    $form = $this->addLanguageWireLogoToForm($form);

    return $this->addProjectsMetadataToForm($form, $projects, $job);
  }

  /**
   * Add LanguageWire logo to form.
   *
   * @param array $form
   *   Form.
   *
   * @return array
   *   Form.
   */
  private function addLanguageWireLogoToForm(array $form): array {
    $form['icon'] = [
      '#type' => 'item',
      '#markup' => $this->t($this->getLanguageWireLogoMarkup()),
    ];
    return $form;
  }

  /**
   * Get LanguageWire logo markup.
   */
  private function getLanguageWireLogoMarkup(): string {
    $modulePath = $this->moduleHandler->getModule(LanguageWireConnector::MODULE_NAME)->getPath();
    $languagewireLogoPath = "/$modulePath/icons/languagewire-orange-black.svg";

    return "<img src='$languagewireLogoPath' width='120' height='19' alt='LanguageWire logo'>";
  }

  /**
   * Add project metadata to form.
   *
   * @param array $form
   *   Form.
   * @param \Drupal\languagewire_translation_provider\Domain\Project[] $projects
   *   Projects.
   * @param \Drupal\languagewire_translation_provider\Adapter\TMGMT\TmgmtJobInterface $job
   *   TMGMT job.
   *
   * @return array
   *   Form.
   */
  private function addProjectsMetadataToForm(array $form, array $projects, TmgmtJobInterface $job): array {
    $form['projects_metadata'] = [
      '#type' => 'item',
      '#title' => $this->t('LanguageWire project information'),
    ];

    foreach ($projects as $i => $project) {
      $this->addProjectMetadataToForm($form['projects_metadata'], $project, $i);

      if ($this->projectsCanBeRetried([$project])) {
        $this->addReimportButtonToForm($form['projects_metadata']['project_' . $i], $job->jobId(), $project->getId());
      }
    }

    return $form;
  }

  /**
   * Add project metadata to form.
   *
   * @param array $subForm
   *   Sub form.
   * @param \Drupal\languagewire_translation_provider\Domain\Project $project
   *   Project.
   * @param int $i
   *   Index.
   */
  private function addProjectMetadataToForm(array &$subForm, Project $project, int $i): void {
    $key = 'project_' . $i;

    $subForm[$key] = [
      '#type' => 'item',
    ];

    if ($project->getPlatformId() > 0) {
      $subForm[$key]['platform_id'] = [
        '#type' => 'item',
        '#title' => $this->t('Platform ID'),
        '#markup' => $project->getPlatformId(),
      ];
    }

    if ($project->hasPlatformUrl()) {
      $url = (string) $project->getPlatformUrl();
      $subForm[$key]['platform_url'] = [
        '#type' => 'item',
        '#title' => $this->t('Platform URL'),
        '#markup' => "<a href='$url'>$url</a>",
      ];
    }

    $subForm[$key]['correlation_id'] = [
      '#type' => 'item',
      '#title' => $this->t('Correlation ID'),
      '#markup' => $project->getCorrelationId(),
    ];

    $subForm[$key]['status'] = [
      '#type' => 'item',
      '#title' => $this->t('Project status'),
      '#markup' => $this->t($this->printableProjectStatus($project->getStatus())),
    ];
  }

  /**
   * Printable project status.
   *
   * @param \Drupal\languagewire_translation_provider\Domain\ProjectStatus $status
   *   Project status.
   *
   * @return string
   *   Printable project status.
   */
  private function printableProjectStatus(ProjectStatus $status): string {
    $statusText = (string) $status;
    return ucwords(str_replace("_", " ", $statusText));
  }

  /**
   * Projects can be retried.
   *
   * @param \Drupal\languagewire_translation_provider\Domain\Project[] $projects
   *   Projects.
   *
   * @return bool
   *   TRUE if projects can be retried, FALSE otherwise.
   */
  private function projectsCanBeRetried(array $projects): bool {
    foreach ($projects as $project) {
      if ($project->canBeReimported()) {
        return TRUE;
      }
    }

    return FALSE;
  }

  /**
   * Add reimport button to form.
   *
   * @param array $subform
   *   Form.
   * @param int $tmgmtJobId
   *   TMGMT job ID.
   * @param int $projectId
   *   Project ID.
   */
  private function addReimportButtonToForm(array &$subform, int $tmgmtJobId, int $projectId): void {
    $nameButton = 'reset_state';

    $subform[$nameButton]['description'] = [
      '#type' => 'item',
      '#title' => $this->t('Reimport project'),
      '#markup' => $this->t("Recover projects so the connector can attempt to download translations"),
    ];

    $reimportProject = $this->t('Reimport project');

    // @todo get this URL dynamically from routes
    $linkMarkup = "<a class='button' href='/admin/languagewire/reimportProjectsFromJob?job_id=$tmgmtJobId&project_id=$projectId'>" . $reimportProject . "</a>";

    $subform[$nameButton]['reimport_link'] = [
      '#type' => 'item',
      '#markup' => $linkMarkup,
    ];
  }

}
