<?php
declare(strict_types=1);

namespace WP_AUX\Entities\AuxFramework\Partials;

use WP_AUX\Services\AuxFramework\ElementClassesService;
use WP_AUX\Services\HtmlService;

class ContactCardEntity
{
  protected string $layout = 'inline';
  protected ?string $name = null;
  protected ?string $title = null;
  protected ?string $org = null;
  protected ?string $email = null;
  protected ?string $phone = null;
  protected ?string $url = null;
  protected ?array $image = null;
  protected ?string $adminName = null;
  protected ?string $adminTitle = null;
  protected ?string $adminEmail = null;
  protected ?string $adminPhone = null;
  protected bool $hasIntro = false;

  public function __construct(?string $name, ?string $title = null, ?string $org = null) {
    $this->name = $name;
    $this->title = $title;
    $this->org = $org;
  }

  public function setContactInfo(?string $email = null, ?string $phone = null, string|array|null $url = null): static
  {
    $this->email = $email;
    $this->phone = $phone;
    $this->url = is_array($url) ? $url['url'] : $url;

    return $this;
  }

  public function setAdminInfo(?string $name, ?string $title = null, ?string $email = null, ?string $phone = null): static
  {
    $this->adminName = $name;
    $this->adminTitle = $title;
    $this->adminEmail = $email;
    $this->adminPhone = $phone;

    return $this;
  }

  public function setImage(array|string|null|bool $image): static
  {
    if (empty($image)) {
      $image = null;
    }

    $this->image = $image;

    return $this;
  }

  public function setLayout(?string $layout): static
  {
    $this->layout = $layout;
    return $this;
  }

  public function setHasIntro(bool $hasIntro): self
  {
    $this->hasIntro = $hasIntro;
    return $this;
  }

  public function getAdminBlock(): string
  {
    $adminName = HtmlService::formattedValue($this->adminName, '<span class="asst__name">%s</span>');
    $adminTitle = HtmlService::formattedValue($this->adminTitle, '<span class="asst__title">%s</span>');

    $adminPieces = [];
    if ($this->adminPhone) {
      $adminPieces[] = $this->adminPhone;
    }
    if ($this->adminEmail) {
      $adminPieces[] = sprintf('<span class="asst__contact"><a href="mailto:%s">%s</a></span>', $this->adminEmail, $this->adminEmail);
    }
    $adminContact = HtmlService::formattedValue(join(' | ', $adminPieces), '<span class="asst__contact">%s</span>');

    // don't show admin block if the name isn't filled out
    $block = '';
    if ($this->adminName) {
      $block = <<<HTML
      <div class="profile-preview__assistant">
        <div class="asst__container">
          <span class="profile-preview__label">Administrative Contact</span>
          $adminName
          $adminTitle
          $adminContact
        </div>
      </div>
  HTML;
    }

    return $block;
  }

  public function __toString(): string
  {
    $contactCardImage = '';
    if ($this->image) {
      $contactCardImage = ImageEntity::create($this->image)->wrap('profile-preview__image');
    }

    $contactCardName = HtmlService::formattedValue($this->name, '<h2 class="info__name">%s</h2>');
    if ($this->hasIntro) {
      $contactCardName = HtmlService::formattedValue($this->name, '<h3 class="info__name">%s</h3>');
    }
    $contactCardTitle = HtmlService::formattedValue($this->title, '<span class="info__title">%s</span>');
    $contactCardOrg = HtmlService::formattedValue($this->org, '<span class="info__institution">%s</span>');

    $contactPieces = [];
    if ($this->email) {
      $contactPieces[] = sprintf('<svg><use href="#aux_envelope"></use></svg><a href="mailto:%s">%s</a>', $this->email, $this->email);
    }
    if ($this->phone) {
      $contactPieces[] = sprintf('<svg><use href="#aux_phone"></use></svg>%s', $this->phone);
    }

    $contactInfo = '';

    if (count($contactPieces) === 1) {
      $contactInfo = sprintf('<p class="info__contact">%s</p>', $contactPieces[0]);
    } elseif (count($contactPieces) > 1) {
      $contactInfo = '<ul class="info__contact">' . join(array_map(function($contactPiece) {
          return sprintf('<li>%s</li>', $contactPiece);
        }, $contactPieces)) . '</ul>';
    }

    $contactInfo .= HtmlService::formattedValue($this->url, '<a href="%s" class="link--cta">View Profile</a>');
    $adminInfo = $this->getAdminBlock();

    $classes = ElementClassesService::buildClasses('profile-preview');
    $classes->addModifier($this->layout);

    $string = <<<HTML
      <div class="$classes">
          $contactCardImage
          <div class="profile-preview__info">
              <div class="info__container">
                  $contactCardName
                  $contactCardTitle
                  $contactCardOrg
              </div>
              $contactInfo
          </div>
          $adminInfo
      </div>
HTML;

    return $string;
  }

  public static function create(?string $name, ?string $title = null, ?string $org = null): static
  {
    $contactCard = new static($name, $title, $org);

    return $contactCard;
  }
}
