<?php

namespace Application\Service\Extension\Helper\base;

use Application\Service\Exceptions\InvalidArgumentException;
use Exception;

abstract class BaseHelper
{
    protected array $attributes = [];

    public static array $cache = [];

    protected bool $withoutCache = false;

    const HELPER_KEY_BASE = 'BASE';

    public function __construct($config = [])
    {
        $this->setAttributes($config);
    }

    public function withoutCache(string $key = ''): BaseHelper
    {
        if ($key) {
            unset(self::$cache[$key]);
        } else {
            self::$cache = [];
        }

        return $this;
    }

    protected function getCache(string $helperKey = self::HELPER_KEY_BASE)
    {
        return self::$cache;
    }
    protected abstract function setCache($value, string $helperKey = self::HELPER_KEY_BASE);
    protected abstract function getCacheKey();

    public function setAttributes($attributes = []): BaseHelper
    {
        foreach ($attributes as $key => $value) {
            if (property_exists($this, $key)) {
                $this->{$key} = $value;
            }
        }

        return $this;
    }

    /**
     * @param $propertyVal
     * @param string $keyName
     * @param string $exceptionMessage
     * @return mixed
     * @throws Exception
     */
    protected function getProperty($propertyVal, string $keyName = '', string $exceptionMessage = '')
    {
        if ($propertyVal === null) {
            throw new Exception("`propertyVal` is null.");
        }

        if (($keyName && !array_key_exists($keyName, $propertyVal))) {
            if (!$exceptionMessage) {
                throw new Exception("`{$keyName}` is invalid.");
            }
            throw new Exception($exceptionMessage);
        }

        return $keyName ? ($propertyVal[$keyName] ?? null) : $propertyVal;
    }
}