<?php

namespace goodboyalex\php_components_pack\models;

use Exception;
use goodboyalex\php_components_pack\classes\ClassMapper;
use goodboyalex\php_components_pack\enums\MessageType;
use goodboyalex\php_components_pack\interfaces\ISerializable;
use UnitEnum;

/**
 * Класс сообщения состояния.
 *
 * @author Александр Бабаев
 * @package php_components_pack
 * @version 1.0
 * @since 1.0
 */
final class ActionStateMessageModel implements ISerializable
{
    /**
     * @var MessageType $MessageType Тип сообщения
     */
    public MessageType $MessageType;

    /**
     * @var bool $IsCritical Критичность сообщения
     */
    public bool $IsCritical;

    /**
     * @var string $Message Текст сообщения
     */
    public string $Message;

    /**
     * Конструктор
     *
     * @param MessageType $type Тип сообщения
     * @param bool $isCritical Критичность сообщения
     * @param string $message Текст сообщения
     */
    public function __construct (MessageType $type = MessageType::Info, bool $isCritical = false, string $message = "")
    {
        $this->MessageType = $type;
        $this->IsCritical = $isCritical;
        $this->Message = $message;
    }

    /**
     * @inheritDoc
     */
    public function UnSerialize (string $serialized): void
    {
        // Десериализую массив
        $thisNew = unserialize($serialized);

        try {
            // Получаю класс
            $class = ClassMapper::MapToClassProperty(get_class($this), $thisNew);
        }
        catch (Exception) {
            $class = new ActionStateMessageModel();
        }

        // Заполняю текущий класс
        ClassMapper::MapClass($class, $this);
    }

    /**
     * @inheritDoc
     */
    public function Serialize (): string
    {
        // Создаю массив результата
        $result = [];

        // Получаю свойства класса
        $properties = get_object_vars($this);

        // Для каждого свойства класса
        foreach ($properties as $key => $value) {

            // - если значение является перечислением
            if ($value instanceof UnitEnum) {
                // -- получаю перечисление
                $result[$key] = $value->name;

                // -- следующий элемент
                continue;
            }

            // - если значение является NULL
            if ($value == null) {
                // -- присваиваю NULL
                $result[$key] = "null";
                // -- следующий элемент
                continue;
            }

            // - присваиваю значение
            $result[$key] = $value;
        }

        // Сериализую массив и вывожу его
        return serialize($result);
    }
}