<?php

declare(strict_types=1);

namespace Drupal\Tests\acquia_dam\Kernel\Plugin\views\field;

use Drupal\acquia_dam\Entity\MediaSourceField;
use Drupal\Core\Render\RenderContext;
use Drupal\media\Entity\Media;
use Drupal\media\MediaTypeInterface;
use Drupal\Tests\acquia_dam\Kernel\AcquiaDamKernelTestBase;
use Drupal\views\Views;

/**
 * Tests the AvailabilityPublishingStatusCompare views plugin field.
 *
 * @group acquia_dam
 */
class AvailabilityPublishingStatusCompareTest extends AcquiaDamKernelTestBase {

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();
    // Install the necessary configuration for the test.
    $this->installConfig([
      'media',
      'media_library',
      'acquia_dam',
      'views',
      'system',
    ]);
  }

  /**
   * Create DAM assets media.
   *
   * This method creates a media entity with the provided data.
   * @param \Drupal\media\MediaTypeInterface $media_type
   *   The media type to use for the media entity.
   * @param string $asset_id
   *   The asset ID to associate with the media entity.
   * @param string $version_id
   *   The version ID to associate with the media entity.
   */
  private function createDamAssetMedia(MediaTypeInterface $media_type, string $asset_id, string $version_id): void {
    // Create a media entity with the provided data.
    $media = Media::create([
      'bundle' => $media_type->id(),
      MediaSourceField::SOURCE_FIELD_NAME => [
        'asset_id' => $asset_id,
        'version_id' => $version_id,
      ],
    ]);
    $media->save();
  }

  /**
   * Tests the render method.
   */
  public function testRender() {
    // Set up the media type for the test.
    $media_type = $this->createDocumentMediaType();
    // Set up the current user with necessary permissions.
    $this->drupalSetUpCurrentUser([], [], TRUE);
    // Create a media entity with the provided data.
    $this->createDamAssetMedia($media_type, '4f656c07-6a08-47b3-9403-16082d2fcda2', 'c6a1d232-4460-43de-afd2-b3bd53ade80f');
    $this->createDamAssetMedia($media_type, 'a56fb261-8ad5-4e0d-8323-0e8a3659ed39', '4f656c07-6a08-47b3-9403-16082d2fcda8');
    $this->createDamAssetMedia($media_type, 'a56fb261-8ad5-4e0d-8323-0e8a3659ed38', '4f656c07-6a08-47b3-9403-16082d2fcda8');
    $this->createDamAssetMedia($media_type, 'c2bbed58-427f-43f7-91d8-c380307dac67', '4f656c07-6a08-47b3-9403-16082d2fcda8');

    // Count the number of media entities created.
    $media_count = Media::loadMultiple();
    self::assertCount(4, $media_count, 'Three media entities were created.');

    // Create a view with the custom field.
    $view = Views::getView('dam_content_overview');
    self::assertNotNull($view);
    $view->setDisplay('default');
    $view->execute();

    /** @var \Drupal\Core\Render\RendererInterface $renderer */
    $renderer = $this->container->get('renderer');

    // Check if the view has the expected field.
    $expectedRows = [
      [
        'sync_message' => 'Availability status of the DAM asset and the published status of the media item match.',
        'sync_status' => 'In sync',
        'dam_status' => 'Released',
        'drupal_status' => 'Published',
      ],
      [
        'sync_message' => 'Availability status of the DAM asset and the published status of the media item match.',
        'sync_status' => 'In sync',
        'dam_status' => 'Unreleased',
        'drupal_status' => 'Unpublished',
      ],
      [
        'sync_message' => 'Availability status of the DAM asset and the published status of the media item match.',
        'sync_status' => 'In sync',
        'dam_status' => 'Expired',
        'drupal_status' => 'Unpublished',
      ],
      [
        'sync_message' => 'Availability status of the DAM asset and the published status of the media item match.',
        'sync_status' => 'In sync',
        'dam_status' => 'Deleted',
        'drupal_status' => 'Unpublished',
      ]
    ];
    $renderer->executeInRenderContext(new RenderContext(), function () use ($view, $expectedRows) {
      foreach ($expectedRows as $index => $row) {
        $actual = $view->field['availability_publishing_status_comparison']->render($view->result[$index]);

        // Test sync message
        $this->assertEquals($row['sync_message'], $actual['#sync_message'], "Sync message should match for row $index");

        // Test sync status (TranslatableMarkup object)
        $this->assertEquals($row['sync_status'], (string) $actual['#sync_status'], "Sync status should match for row $index");

        // Test DAM status (TranslatableMarkup object)
        $this->assertEquals($row['dam_status'], (string) $actual['#dam_status'], "DAM status should match for row $index");

        // Test Drupal status (TranslatableMarkup object)
        $this->assertEquals($row['drupal_status'], (string) $actual['#drupal_status'], "Drupal status should match for row $index");
      }
    });
  }

}
