<?php
declare(strict_types=1);

namespace WP_AUX\Entities\AuxFramework\Partials;

use WHOOP\Entities\Element;
use WHOOP\Entities\Elements\Div;
use WHOOP\Entities\Elements\Figcaption;
use WHOOP\Entities\Elements\Figure;
use WHOOP\Entities\Elements\Img;
use WP_AUX\Entities\Embeds\VideoEmbedEntity;
use WP_AUX\Services\AuxFramework\ElementClassesService;
use WP_AUX\Services\HtmlService;

class CaptionedMediaEntity
{
  protected ImageEntity|VideoEmbedEntity|null $media = null;
  protected Figure $figure;
  protected Figcaption $figcaption;
  protected ?string $captionCredit = null;
  protected ?string $captionContent = null;
  protected ?string $style = null;
  protected bool $isSlab = false;
  protected bool $isDarkMode = false;
  protected bool $isSidebar = false;
  protected ?string $align = null;

  public function __construct(Img|ImageEntity|VideoEmbedEntity $media) {
    $this->figure = Figure::create(null);
    $this->figcaption = Figcaption::create(null);
    $this->media = $media;

    $this->figure->appendElement($this->media);
    $this->figure->appendElement($this->figcaption);
  }

  public function getFigure(): Figure
  {
    return $this->figure;
  }

  public function getFigcaption(): Figcaption
  {
    return $this->figcaption;
  }

  public function setStyle(string $style): self
  {
    $this->style = $style;
    return $this;
  }

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

  public function setAlign(string $align): self
  {
    $this->align = $align;
    return $this;
  }

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

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

  public function setCaptionCredit(?string $captionCredit): self
  {
    $this->captionCredit = $captionCredit;
    return $this;
  }

  public function setCaptionContent(?string $captionContent): self
  {
    $this->captionContent = $captionContent;
    return $this;
  }

  public function __toString(): string
  {
    $captionClasses = ElementClassesService::buildClasses('caption');

    $figureClasses = ElementClassesService::buildClasses('captioned-media');
    if (in_array($this->align, ['left', 'right'])) {
      $figureClasses->addModifier($this->align);
      $figureClasses->addModifier('small');
    }

    if ($this->isSlab) {
      $figureClasses->addModifier('slab');
      $captionClasses->addModifier('slab');
    }

    if ($this->isSidebar) {
      $figureClasses->addModifier('sidebar');
    }

    if ($this->media instanceof VideoEmbedEntity) {
      $figureClasses->addModifier('video');
    }

    if ($this->style && 'default' !== $this->style) {
      $captionClasses->addModifier($this->style);
    }

    if ($this->isDarkMode) {
      $captionClasses->addModifier('dark-mode');
    }

    $content = [
      HtmlService::formattedValue(
        $this->captionContent,
        '<div class="caption__content"><p>%s</p></div>'
      ),
      HtmlService::formattedValue(
        $this->captionCredit,
        '<div class="caption__credit"><svg><use href="#aux_camera"></use></svg><span>Credit: %s</span></div>'
      )
    ];

    $this->figcaption->addClass((string) $captionClasses);
    $this->figure->addClass((string) $figureClasses);

    $this->figcaption->setContent($content);

    return (string) $this->figure;
  }

  public static function create(array|string|Img $file, string $mediaType = 'image', ?string $captionContent = null, ?string $captionCredit = null): static
  {
    if ('video' === $mediaType) {
      $media = VideoEmbedEntity::create(
        $file,
      );
    } else {
      $media = ImageEntity::create($file);
    }

    $captionedMedia = new static($media);

    if ($captionContent) {
      $captionedMedia->setCaptionContent($captionContent);
    }

    if ($captionCredit) {
      $captionedMedia->setCaptionCredit($captionCredit);
    }

    return $captionedMedia;
  }

  public static function createImage(array|string|Img $image, ?string $captionContent = null, ?string $captionCredit = null): static
  {
    return static::create($image, 'image', $captionContent, $captionCredit);
  }
}
