<?php

namespace Ui\CheckoutUi;

use Drupal\languagewire_translation_provider\Adapter\TMGMT\LanguageMapping;
use Drupal\languagewire_translation_provider\Adapter\TMGMT\TmgmtJobInterface;
use Drupal\languagewire_translation_provider\Test\Builder\Domain\ProjectTemplateBuilder;
use Drupal\languagewire_translation_provider\Test\Builder\TmgmtJobBuilder;
use Drupal\languagewire_translation_provider\Ui\CheckoutUi\TemplateOrServiceFormValidator;
use PHPUnit\Framework\TestCase;

/**
 * Template Or Service Form Validator Test .
 */
class TemplateOrServiceFormValidatorTest extends TestCase {
  use \Prophecy\PhpUnit\ProphecyTrait;

  /**
   * Element .
   *
   * @var array
   */
  private $element;

  /**
   * Job .
   *
   * @var \Prophecy\Prophecy\ObjectProphecy
   */
  private $job;

  /**
   * Set Up .
   */
  protected function setUp(): void {
    $this->element = [
      '#value' => "",
      '#title' => "Template or Service",
    ];
    $this->job = $this->prophesize(TmgmtJobInterface::class);
  }

  /**
   * When Template Is Not Selected Then No Errors Are Returned .
   *
   * @test
   */
  public function whenTemplateIsNotSelectedThenNoErrorsAreReturned() {
    $sut = new TemplateOrServiceFormValidator($this->job->reveal(), []);
    $this->setElementValue("non_template_prefix");

    $errors = $sut->validateDropdown($this->element);

    $this->assertCount(0, $errors);
  }

  /**
   * When Missing Template Is Selected Then Missing Template Error Is Returned .
   *
   * @test
   */
  public function whenMissingTemplateIsSelectedThenMissingTemplateErrorIsReturned() {
    $sut = new TemplateOrServiceFormValidator($this->job->reveal(), []);
    $this->setElementValue("template_123");

    $errors = $sut->validateDropdown($this->element);

    $this->assertCount(1, $errors);
    $this->assertContains('The provided project template does not exist', $errors);
  }

  /**
   * When Existing Template Is Selected Then No Errors Are Returned .
   *
   * @test
   */
  public function whenExistingTemplateIsSelectedThenNoErrorsAreReturned() {
    $projectTemplate = (new ProjectTemplateBuilder())
      ->withPlatformId(123)
      ->withSourceLanguage('en-US')
      ->withTargetLanguages(['es-ES'])
      ->build();

    $job = (new TmgmtJobBuilder())
      ->withSourceLanguage(new LanguageMapping('en', 'en-US'))
      ->withTargetLanguage(new LanguageMapping('es', 'es-ES'))
      ->build();

    $sut = new TemplateOrServiceFormValidator($job, [$projectTemplate]);
    $this->setElementValue("template_123");

    $errors = $sut->validateDropdown($this->element);

    $this->assertCount(0, $errors);
  }

  /**
   * When Template Selected And No Match Source Then Error Is Returned .
   *
   * @test
   */
  public function whenExistingTemplateIsSelectedAndDoesntMatchSourceThenErrorIsReturned() {
    $projectTemplate = (new ProjectTemplateBuilder())
      ->withPlatformId(123)
      ->withSourceLanguage('en-US')
      ->withTargetLanguages(['es-ES'])
      ->build();

    $job = (new TmgmtJobBuilder())
      ->withSourceLanguage(new LanguageMapping('it', 'it-IT'))
      ->withTargetLanguage(new LanguageMapping('es', 'es-ES'))
      ->build();

    $sut = new TemplateOrServiceFormValidator($job, [$projectTemplate]);
    $this->setElementValue("template_123");

    $errors = $sut->validateDropdown($this->element);

    $this->assertCount(1, $errors);
    $this->assertContains('The current project template is not configured to have "it" ("it-IT") as a source language.', $errors);
  }

  /**
   * When Template Selected And No Match Target Then Error Is Returned .
   *
   * @test
   */
  public function whenExistingTemplateIsSelectedAndDoesntMatchTargetThenErrorIsReturned() {
    $projectTemplate = (new ProjectTemplateBuilder())
      ->withPlatformId(123)
      ->withSourceLanguage('en-US')
      ->withTargetLanguages(['es-ES'])
      ->build();

    $job = (new TmgmtJobBuilder())
      ->withSourceLanguage(new LanguageMapping('en', 'en-US'))
      ->withTargetLanguage(new LanguageMapping('it', 'it-IT'))
      ->build();

    $sut = new TemplateOrServiceFormValidator($job, [$projectTemplate]);
    $this->setElementValue("template_123");

    $errors = $sut->validateDropdown($this->element);

    $this->assertCount(1, $errors);
    $this->assertContains('The current project template is not configured to have "it" ("it-IT") as a target language.', $errors);
  }

  /**
   * Set Element Value .
   */
  private function setElementValue(string $value) {
    $this->element['#value'] = $value;
  }

}
