<?php
/**
 * @package DJ-Catalog2-Yootheme
 * @copyright Copyright (C) DJ-Extensions.com, All rights reserved.
 * @license http://www.gnu.org/licenses GNU/GPL
 * @author url: http://dj-extensions.com
 * @author email contact@dj-extensions.com
 */

namespace DJExtensions\DJCatalog2\YOOtheme\Presets;
defined('_JEXEC') or die;
use function YOOtheme\app;
use YOOtheme\Config;
use YOOtheme\File;
use YOOtheme\Path;
use YOOtheme\Str;

class Presets
{
    /**
     * @var Cache
     */
    public $cache;

    /**
     * @var Config
     */
    public $config;

    /**
     * @var array
     */
    public $typesUbications = [
        '~djcatalog2/modules/presets/presets'
    ];
    /**
     * Queue for presets to be loaded
     *
     * @var array
     */
    public $queue = [];

    /**
     * Constructor.
     */
    public function __construct(Config $config)
    {
        $this->config = $config;
        $this->cache = new Cache('preset');
    }

    /**
     * Determines if the feature is enabled
     *
     * @return Boolean
     */
    public function isEnabled()
    {
        return app()->config->get('~theme.djcatalog2.presets.state', 1);
    }

    /**
     * Add a directory where to look for icons collections
     *
     * @return Array
     */
    public function addTypesDir($dir)
    {
        $this->typesUbications[] = $dir;
    }
    public function load(string $preset)
    {
        $isProvided = Str::contains($preset, '--');

        if (!$isProvided) {
            return;
        }

        $content = $this->cache->get("{$preset}.json");

        if (!$content and $file = $this->find($preset)) {
            $content = File::getContents($file);
            $this->cache->set("{$preset}.json", $content);
        }

        if ($content) {
            $this->queue[$preset] = $content;
        }
    }

    /**
     * Returns the presets that were queued for loading, and their content
     *
     * @return Array
     */
    public function getQueued()
    {
        return $this->queue;
    }


    /**
     * Finds the preset and returns it first ubication path
     *
     * @return String
     */
    protected function find($preset)
    {
        list('type' => $type, 'group' => $group, 'name' => $name) = $this->parseValue($preset);

        $basepath = Path::join($group, $name);

        if ($type === 'mypresets' and $dir = $this->config->get('theme.childDir') ?? false and $file = File::find("$dir/mypresets/$basepath.svg")) {
            return $file;
        }

        foreach ($this->typesUbications as $dir) {
            if ($file = File::find("$dir/$type/$basepath.json")) {
                return $file;
            }
        }
    }

    /**
     * Parse preset info from it value
     *
     * @return Array
     */
    protected function parseValue($preset)
    {
        preg_match('/^([^-]*)-?(.*)--(.*)$/', $preset, $matches);
        list($match, $type, $group, $name) = $matches;

        return compact('type', 'group', 'name');
    }

    /**
     * Retrieve all presets that should be loaded from a node
     *
     * @return Array
     */
    public function retrievePresets($node, $type)
    {
        $presets = [];
        $fields = $type->data['fields'] ?? [];

        // get all fields key of type 'preset'
        $fieldsKeys = array_keys(array_filter($fields, function ($v) {
            return in_array($v['type'] ?? '', [
                'preset',
                'button_preset'
            ]);
        }));

        foreach ($fieldsKeys as $key) {
            $value = $node->props[$key] ?? false;

            if (is_string($value)) {
                // preset could be set raw or with attributes (unusual but still expected),
                // we always explode and assume the preset name is set first
                list($presetName) = explode(';', $value);

                $presets[] = trim($presetName);
            }
        }

        return $presets;
    }

    /**
     * Retrieve presets list from all fieldsthat should be loaded from a node
     *
     * @return Array
     */
    public function retrievePresetsHtml($node, $type)
    {
        $presets = [];
        $fields = $type->data['fields'] ?? [];

        // iterate all fields
        foreach (array_keys($fields) as $key) {
            $value = $node->props[$key] ?? false;

            if (is_string($value)) {
                preg_match('/preset: ([\w-]*--[\w-]*)/', $value, $matches);
            }

            if ($matches[1] ?? false) {
                $presets[] = $matches[1];
            }
        }

        return $presets;
    }
}
