<?php

namespace Drupal\Tests\commerce_order\FunctionalJavascript;

/**
 * Tests the commerce_order reassign form.
 *
 * @group commerce
 */
class OrderReassignTest extends OrderWebDriverTestBase {

  /**
   * A test order.
   *
   * @var \Drupal\commerce_order\Entity\OrderInterface
   */
  protected $order;

  /**
   * Modules to enable.
   *
   * @var array
   */
  protected static $modules = [
    'commerce_product',
    'commerce_order',
    'inline_entity_form',
  ];

  /**
   * {@inheritdoc}
   */
  protected function getAdministratorPermissions() {
    return array_merge([
      'administer commerce_order',
      'administer commerce_order_type',
    ], parent::getAdministratorPermissions());
  }

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();

    $order_item = $this->createEntity('commerce_order_item', [
      'type' => 'default',
      'unit_price' => [
        'number' => '999',
        'currency_code' => 'USD',
      ],
    ]);
    /** @var \Drupal\commerce_order\Entity\OrderInterface $order */
    $this->order = $this->createEntity('commerce_order', [
      'type' => 'default',
      'mail' => $this->loggedInUser->getEmail(),
      'uid' => $this->loggedInUser->id(),
      'order_items' => [$order_item],
      'store_id' => $this->store,
    ]);
  }

  /**
   * Tests the reassign form with a new user.
   */
  public function testReassignToNewUser(): void {
    $this->drupalGet($this->order->toUrl('reassign-form'));
    $this->getSession()->getPage()->fillField('customer_type', 'new');
    $this->assertSession()->assertWaitOnAjaxRequest();
    $values = [
      'mail' => 'example@example.com',
    ];
    $this->submitForm($values, 'Reassign order');
    $collection_url = $this->order->toUrl('canonical', ['absolute' => TRUE]);
    $this->assertSession()->addressEquals($collection_url);
    $this->assertSession()->pageTextContains($this->t('The @label has been assigned to customer @customer.', [
      '@label' => $this->order->label(),
      '@customer' => 'example@example.com',
    ]));

    $this->order = $this->reloadEntity($this->order);
    $this->assertNotEquals($this->loggedInUser->id(), $this->order->getCustomerId());
    $this->assertEquals('example@example.com', $this->order->getCustomer()->getEmail());
  }

  /**
   * Tests the reassign form with an existing user.
   */
  public function testReassignToExistingUser(): void {
    $another_user = $this->createUser();
    $this->drupalGet($this->order->toUrl('reassign-form'));
    $this->submitForm(['uid' => $another_user->getAccountName()], 'Reassign order');
    $collection_url = $this->order->toUrl('canonical', ['absolute' => TRUE]);
    $this->assertSession()->addressEquals($collection_url);
    $this->assertSession()->pageTextContains($this->t('The @label has been assigned to customer @customer.', [
      '@label' => $this->order->label(),
      '@customer' => $another_user->getAccountName(),
    ]));

    $this->order = $this->reloadEntity($this->order);
    $this->assertEquals($another_user->id(), $this->order->getCustomerId());
  }

  /**
   * Tests reassign in the modal.
   */
  public function testReassignFromModal(): void {
    $another_user = $this->createUser();

    // Confirm that "Reassign order" link exists and it opens the modal form.
    $this->drupalGet($this->order->toUrl());
    $this->assertSession()->linkExists('Reassign order');
    $this->getSession()->getPage()->clickLink('Reassign order');
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->assertSession()->elementTextContains('css', '.ui-dialog .ui-dialog-title', 'Reassign order');

    // Fill info for new assignment.
    $this->getSession()->getPage()->fillField('uid', $another_user->getAccountName());
    $this->assertSession()->waitOnAutocomplete();
    $this->assertCount(1, $this->getSession()->getPage()->findAll('css', '.ui-autocomplete li'));
    $this->getSession()->getPage()->find('css', '.ui-autocomplete li:first-child a')->click();
    $this->getSession()->getPage()->find('css', '.ui-dialog .ui-dialog-buttonpane')->findButton('Reassign order');
    $this->getSession()->getPage()->find('css', '.ui-dialog .ui-dialog-buttonpane')->pressButton('Reassign order');

    // Confirm that order is reassigned.
    $this->assertSession()->pageTextContains($this->t('The @label has been assigned to customer @customer.', [
      '@label' => $this->order->label(),
      '@customer' => $another_user->getAccountName(),
    ]));
    $this->order = $this->reloadEntity($this->order);
    $this->assertEquals($another_user->id(), $this->order->getCustomerId());
  }

}
