<?php

namespace Drupal\social\Behat\Mailpit;

/**
 * Represents a summary of a message in the Mailpit API used in lists.
 */
readonly class MessageSummary {

  use AssertDataStructureTrait;

  /**
   * Create a new message data object.
   *
   * @param string $id
   *   The Mailpit ID of the email.
   * @param string $messageId
   *   Message-ID is a unique identifier for a digital message.
   *   If present, are generated by the client program sending the email[2] or
   *   by the first mail server.[3] A common method of generating such ID is by
   *   combining the time and domain name, for example:
   *   950124.162336@param bool $read
   *   Whether the message has been read or not.
   * @param Addressee $from
   *   The sender of the email.
   * @param Addressee[] $to
   *   The recipients of the email.
   * @param Addressee[] $cc
   *   The carbon copy recipients of the email.
   * @param Addressee[] $bcc
   *   The blind carbon copy recipients of the email.
   * @param Addressee[] $replyTo
   *   The reply to list of the email.
   * @param string $subject
   *   The subject of the email.
   * @param \DateTimeImmutable $created
   *   The date the email was sent.
   * @param string[] $tags
   *   Any Mailpit tags that are associated with the email.
   * @param string $snippet
   *   Message snippet includes up to 250 characters.
   * @param int $size
   *   The size in bytes of the email.
   * @param int $attachments
   *   The number of attachments in the email.
   *
   *@example.com.
   */
  public function __construct(
    public string $id,
    public string $messageId,
    public bool $read,
    public Addressee $from,
    public array $to,
    public array $cc,
    public array $bcc,
    public array $replyTo,
    public string $subject,
    public \DateTimeImmutable $created,
    public array $tags,
    public string $snippet,
    public int $size,
    public int $attachments,
  ) {}

  /**
   * Create the data object from an array of values.
   *
   * @param array $data
   *   The array of values as provided by the API.
   *
   * @return self
   *   The data object.
   */
  public static function fromArray(array $data) : self {
    static::assertHasFields(
      $data,
      [
        'ID',
        'MessageID',
        'Read',
        'From',
        'To',
        'Cc',
        'Bcc',
        'ReplyTo',
        'Subject',
        'Created',
        'Username',
        'Tags',
        'Snippet',
        'Size',
        'Attachments',
      ],
      "Unexpected JSON object from Mailpit, expected message in format from `/api/v1/#get-/api/v1/search` documentation."
    );

    return new static(
      id: $data['ID'],
      messageId: $data['MessageID'],
      read: $data['Read'],
      from: Addressee::fromArray($data['From']),
      to: array_map([Addressee::class, "fromArray"], $data['To']),
      cc: array_map([Addressee::class, "fromArray"], $data['Cc'] ?? []),
      bcc: array_map([Addressee::class, "fromArray"], $data['Bcc'] ?? []),
      replyTo: array_map([Addressee::class, "fromArray"], $data['ReplyTo'] ?? []),
      subject: $data['Subject'],
      created: new \DateTimeImmutable($data['Created']),
      tags: $data['Tags'],
      snippet: $data['Snippet'],
      size: $data['Size'],
      attachments: $data['Attachments'],
    );
  }

}
