<?php

namespace Drupal\languagewire_translation_provider\Test\Database;

use Drupal\languagewire_translation_provider\Adapter\Database\LanguageWireConfigurationItemRepositoryInterface;
use Drupal\languagewire_translation_provider\Adapter\TMGMT\TmgmtTranslatorInterface;
use Drupal\languagewire_translation_provider\Client\InvoicingAccount;
use Drupal\languagewire_translation_provider\Database\TypedInvoicingAccountRepository;
use PHPUnit\Framework\TestCase;
use stdClass;

/**
 * Typed Invoicing Account Repository Test.
 */
class TypedInvoicingAccountRepositoryTest extends TestCase {
  use \Prophecy\PhpUnit\ProphecyTrait;

  /**
   * Config Item Repository .
   *
   * @var \Prophecy\Prophecy\ObjectProphecy
   */
  private $configItemRepository;

  /**
   * Translator .
   *
   * @var \Prophecy\Prophecy\ObjectProphecy
   */
  private $translator;

  /**
   * Set Up .
   */
  protected function setUp(): void {
    $this->configItemRepository = $this->prophesize(LanguageWireConfigurationItemRepositoryInterface::class);
    $this->translator = $this->prophesize(TmgmtTranslatorInterface::class);
  }

  /**
   * Removes All Configuration Items Stored For Translator .
   *
   * @test
   */
  public function removesAllConfigurationItemsStoredForTranslator(): void {
    $translator = $this->translator->reveal();
    $repository = $this->repository();

    $repository->removeAll($translator);

    $this->configItemRepository->removeAll($translator, 'invoicing_account')
      ->shouldHaveBeenCalled();
  }

  /**
   * Saves All Configuration Items For Translator .
   *
   * @test
   */
  public function savesAllConfigurationItemsForTranslator(): void {
    $translator = $this->translator->reveal();
    $items = [];
    $repository = $this->repository();

    $repository->saveAll($items, $translator);

    $this->configItemRepository->saveAll($items, $translator, 'invoicing_account')
      ->shouldHaveBeenCalled();
  }

  /**
   * Fetches All Configuration Items For Translator .
   *
   * @test
   */
  public function fetchesAllConfigurationItemsForTranslator(): void {
    $translator = $this->translator->reveal();
    $databaseItem = $this->databaseItem();
    $this->configItemRepository->getAll($translator, 'invoicing_account')
      ->willReturn([$databaseItem]);
    $repository = $this->repository();

    $result = $repository->getAll($translator);

    $this->assertCount(1, $result);
    $invoicingAccount = $result[0];
    $this->assertInstanceOf(InvoicingAccount::class, $invoicingAccount);
    $this->assertSame($databaseItem->item_id, $invoicingAccount->id());
    $this->assertSame($databaseItem->name, $invoicingAccount->name());
  }

  /**
   * Fetches Invoicing Account By Id .
   *
   * @test
   */
  public function fetchesInvoicingAccountById(): void {
    $invoicingAccountId = 1;
    $translator = $this->translator->reveal();
    $databaseItem = $this->databaseItem();
    $this->configItemRepository->getByIdAndType($translator, $invoicingAccountId, 'invoicing_account')
      ->willReturn($databaseItem);
    $repository = $this->repository();

    $invoicingAccount = $repository->getById($invoicingAccountId, $translator);

    $this->assertInstanceOf(InvoicingAccount::class, $invoicingAccount);
    $this->assertSame($databaseItem->item_id, $invoicingAccount->id());
    $this->assertSame($databaseItem->name, $invoicingAccount->name());
  }

  /**
   * Repository .
   */
  private function repository(): TypedInvoicingAccountRepository {
    return new TypedInvoicingAccountRepository($this->configItemRepository->reveal());
  }

  /**
   * Database Item .
   */
  private function databaseItem(): stdClass {
    $item = new stdClass();
    $item->item_id = 1;
    $item->name = 'Foo';

    return $item;
  }

}
