<?php

declare(strict_types=1);

namespace DigiComp\AssetAttributes\Domain\Model;

use Doctrine\ORM\Mapping as ORM;
use Neos\Flow\Annotations as Flow;

/**
 * @Flow\ValueObject(embedded=false)
 * @ORM\Table(
 *     indexes={
 *         @ORM\Index(columns={"name", "value"})
 *     }
 * )
 */
class AssetAttribute
{
    protected const MAX_VALUE_LENGTH = 250;

    /**
     * @var string
     */
    protected string $name;

    /**
     * @var string
     */
    protected string $value;

    /**
     * @var string
     */
    protected string $urlValue;

    /**
     * @Flow\Transient
     * @Flow\InjectConfiguration(package="DigiComp.AssetAttributes", path="urlReplacements")
     * @var array
     */
    protected array $replacementMap;

    /**
     * @ORM\Column(type="text", nullable=true)
     * @var string|null
     */
    protected ?string $longValue = null;

    /**
     * @param string $name
     * @param string $value
     * @param string $urlValue
     */
    public function __construct(string $name, string $value, string $urlValue = '')
    {
        $this->name = $name;
        if (\mb_strlen($value) > self::MAX_VALUE_LENGTH) {
            $this->longValue = $value;
            $this->value = \mb_substr($value, 0, 250);
        } else {
            $this->value = $value;
        }
        if (!$urlValue) {
            $urlValue = \mb_substr($this->value, 0, 250);
        }
        $this->urlValue = $urlValue;
    }

    public function initializeObject(): void
    {
        if ($this->urlValue === $this->value) {
            $this->urlValue = \str_replace(
                \array_column($this->replacementMap, 'key'),
                \array_column($this->replacementMap, 'value'),
                $this->urlValue
            );
            $this->urlValue = \urlencode(\strtolower($this->urlValue));
        }
    }

    /**
     * @return string
     */
    public function getName(): string
    {
        return $this->name;
    }

    /**
     * @return string
     */
    public function getValue(): string
    {
        return $this->longValue ?? $this->value;
    }

    /**
     * @return string
     */
    public function getUrlValue(): string
    {
        return $this->urlValue;
    }

    /**
     * @return string
     */
    public function __toString(): string
    {
        return $this->getName() . ': ' . $this->getValue();
    }
}