<?php

namespace Drupal\Tests\visitors\Unit\Service;

use Drupal\Tests\UnitTestCase;
use Drupal\visitors\Service\CampaignService;

/**
 * Tests the CampaignService.
 *
 * @coversDefaultClass \Drupal\visitors\Service\CampaignService
 * @group visitors
 */
class CampaignServiceTest extends UnitTestCase {

  /**
   * The campaign service.
   *
   * @var \Drupal\visitors\Service\CampaignService
   */
  protected $campaignService;

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();
    $this->campaignService = new CampaignService();
  }

  /**
   * Tests parsing mtm_* parameters.
   *
   * @covers ::parse
   */
  public function testParseMtmParameters(): void {
    $query = 'mtm_campaign=Best-Seller&mtm_source=Newsletter_7&mtm_medium=email&mtm_keyword=discount&mtm_content=banner&mtm_cid=12345&mtm_group=holiday&mtm_placement=sidebar';

    $result = $this->campaignService->parse($query);

    $this->assertNotNull($result);
    $this->assertEquals('Best-Seller', $result['campaign']);
    $this->assertEquals('Newsletter_7', $result['source']);
    $this->assertEquals('email', $result['medium']);
    $this->assertEquals('discount', $result['keyword']);
    $this->assertEquals('banner', $result['content']);
    $this->assertEquals('12345', $result['campaign_id']);
    $this->assertEquals('holiday', $result['group']);
    $this->assertEquals('sidebar', $result['placement']);
  }

  /**
   * Tests parsing utm_* parameters.
   *
   * @covers ::parse
   */
  public function testParseUtmParameters(): void {
    $query = 'utm_campaign=Summer_Sale&utm_source=google&utm_medium=cpc&utm_term=summer+sale&utm_content=text_ad&utm_id=67890';

    $result = $this->campaignService->parse($query);

    $this->assertNotNull($result);
    $this->assertEquals('Summer_Sale', $result['campaign']);
    $this->assertEquals('google', $result['source']);
    $this->assertEquals('cpc', $result['medium']);
    $this->assertEquals('summer sale', $result['keyword']);
    $this->assertEquals('text_ad', $result['content']);
    $this->assertEquals('67890', $result['campaign_id']);
  }

  /**
   * Tests parsing mixed mtm_* and utm_* parameters.
   *
   * @covers ::parse
   */
  public function testParseMixedParameters(): void {
    $query = 'mtm_campaign=Holiday_Special&utm_source=facebook&utm_medium=social&mtm_content=video';

    $result = $this->campaignService->parse($query);

    $this->assertNotNull($result);
    $this->assertEquals('Holiday_Special', $result['campaign']);
    $this->assertEquals('facebook', $result['source']);
    $this->assertEquals('social', $result['medium']);
    $this->assertEquals('video', $result['content']);
  }

  /**
   * Tests that mtm_* parameters take precedence over utm_* parameters.
   *
   * @covers ::parse
   */
  public function testMtmPrecedenceOverUtm(): void {
    $query = 'mtm_campaign=MTM_Campaign&utm_campaign=UTM_Campaign&mtm_source=MTM_Source&utm_source=UTM_Source';

    $result = $this->campaignService->parse($query);

    $this->assertNotNull($result);
    $this->assertEquals('MTM_Campaign', $result['campaign']);
    $this->assertEquals('MTM_Source', $result['source']);
  }

  /**
   * Tests parsing with empty values.
   *
   * @covers ::parse
   */
  public function testParseWithEmptyValues(): void {
    $query = 'mtm_campaign=&mtm_source=&mtm_medium=email';

    $result = $this->campaignService->parse($query);

    $this->assertNotNull($result);
    $this->assertCount(1, $result);
    $this->assertEquals('email', $result['medium']);
  }

  /**
   * Tests parsing with whitespace.
   *
   * @covers ::parse
   */
  public function testParseWithWhitespace(): void {
    $query = 'mtm_campaign=  Campaign  &mtm_source=  Source  ';

    $result = $this->campaignService->parse($query);

    $this->assertNotNull($result);
    $this->assertEquals('Campaign', $result['campaign']);
    $this->assertEquals('Source', $result['source']);
  }

  /**
   * Tests parsing with no campaign parameters.
   *
   * @covers ::parse
   */
  public function testParseWithNoCampaignParameters(): void {
    $query = 'page=1&sort=date&filter=active';

    $result = $this->campaignService->parse($query);

    $this->assertNull($result);
  }

  /**
   * Tests parsing with null query.
   *
   * @covers ::parse
   */
  public function testParseWithNullQuery(): void {
    $result = $this->campaignService->parse(NULL);

    $this->assertNull($result);
  }

  /**
   * Tests parsing with empty string query.
   *
   * @covers ::parse
   */
  public function testParseWithEmptyStringQuery(): void {
    $result = $this->campaignService->parse('');

    $this->assertNull($result);
  }

  /**
   * Tests parsing with special characters in values.
   *
   * @covers ::parse
   */
  public function testParseWithSpecialCharacters(): void {
    $query = 'mtm_campaign=Campaign%20with%20spaces&mtm_source=Source-with-dashes&mtm_medium=email+newsletter';

    $result = $this->campaignService->parse($query);

    $this->assertNotNull($result);
    $this->assertEquals('Campaign with spaces', $result['campaign']);
    $this->assertEquals('Source-with-dashes', $result['source']);
    $this->assertEquals('email newsletter', $result['medium']);
  }

}
