<?php
/**
 * @copyright (c) Kufer Software GmbH, Loisachstrasse 4, D-84453 Mühldorf
 */

declare(strict_types = 1);

namespace Kufer\Mail\Sender\Result;

final class EMailSentResult
{
  
  protected $sentRecipients;

  
  public function __construct(array $sentRecipients)
  {
    $this->sentRecipients = $sentRecipients;
  }

  
  public function getRecipients(): array
  {
    return $this->sentRecipients;
  }

  
  public function hasSentAllMails(): bool
  {
    return !$this->hasError();
  }

  
  public function hasSentAnyMails(): bool
  {
    return $this->hasSuccess() || $this->hasWarning();
  }

  
  public function hasSuccess(): bool
  {
    return \ArrayOperations::any($this->sentRecipients, function(EMailSentRecipient $recipient) {
      return $recipient->isSuccess();
    });
  }

  
  public function hasWarning(): bool
  {
    return \ArrayOperations::any($this->sentRecipients, function(EMailSentRecipient $recipient) {
      return $recipient->isWarning();
    });
  }

  
  public function hasError(): bool
  {
    return \ArrayOperations::any($this->sentRecipients, function(EMailSentRecipient $recipient) {
      return $recipient->isError();
    });
  }

  
  public function getSuccess(): array
  {
    return \array_filter($this->sentRecipients, function(EMailSentRecipient $recipient) {
      return $recipient->isSuccess();
    });
  }

  
  public function getWarnings(): array
  {
    return \array_filter($this->sentRecipients, function(EMailSentRecipient $recipient) {
      return $recipient->isWarning();
    });
  }

  
  public function getErrors(): array
  {
    return \array_filter($this->sentRecipients, function(EMailSentRecipient $recipient) {
      return $recipient->isError();
    });
  }

  
  public function getUniqueSuccessMessages(): array
  {
    return \array_unique(\array_map(function(EMailSentRecipient $recipient) {
      return $recipient->getReadableMessage();
    }, $this->getSuccess()));
  }

  
  public function getUniqueWarningMessages(): array
  {
    return \array_unique(\array_map(function(EMailSentRecipient $recipient) {
      return $recipient->getReadableMessage();
    }, $this->getWarnings()));
  }

  
  public function getUniqueErrorMessages(): array
  {
    return \array_unique(\array_map(function(EMailSentRecipient $recipient) {
      return $recipient->getReadableMessage();
    }, $this->getErrors()));
  }

  public function toReadableMessages(): EMailSentMessages
  {
    return new EMailSentMessages(
      $this->getUniqueSuccessMessages(),
      $this->getUniqueWarningMessages(),
      $this->getUniqueErrorMessages()
    );
  }

  public function getSuccessMessagesWithNames(bool $showEmail = false): array
  {
    return \array_map(function(EMailSentRecipient $recipient) use ($showEmail) {
      return $recipient->getReadableMessageWithRecipientName($showEmail);
    }, $this->getSuccess());
  }

  public function getWarningMessagesWithNames(bool $showEmail = false): array
  {
    return \array_map(function(EMailSentRecipient $recipient) use ($showEmail) {
      return $recipient->getReadableMessageWithRecipientName($showEmail);
    }, $this->getWarnings());
  }

  public function getErrorMessagesWithNames(bool $showEmail = false): array
  {
    return \array_map(function(EMailSentRecipient $recipient) use ($showEmail) {
      return $recipient->getReadableMessageWithRecipientName($showEmail);
    }, $this->getErrors());
  }

  public function toReadableMessagesWithRecipientNames(bool $showEmail = false): EMailSentMessages
  {
    return new EMailSentMessages(
      $this->getSuccessMessagesWithNames($showEmail),
      $this->getWarningMessagesWithNames($showEmail),
      $this->getErrorMessagesWithNames($showEmail)
    );
  }

  
  public function merge(EMailSentResult $result): EMailSentResult
  {
    return new EMailSentResult(\array_merge(\array_values($this->getRecipients()), \array_values($result->getRecipients())));
  }

  public function hasPosition(string $position): bool
  {
    return \ArrayOperations::any($this->getRecipients(), function(EMailSentRecipient $recipient) use ($position) {
      return $recipient->getRecipientGroupName() === $position;
    });
  }

  public function findByPosition(string $position): ?EMailSentRecipient
  {
    $key = \ArrayOperations::find(function(EMailSentRecipient $recipient) use ($position) {
      return $recipient->getRecipientGroupName() === $position;
    }, $this->getRecipients());

    return \is_null($key) ? null : $this->getRecipients()[$key];
  }
}