<?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\Layouts;
defined('_JEXEC') or die;
use function YOOtheme\app;
use YOOtheme\Config;
use YOOtheme\File;
use YOOtheme\Path;
use YOOtheme\Str;

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

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

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

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

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

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

        if (!$isProvided) {
            return;
        }

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

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

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

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


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

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

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

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

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

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

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

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

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

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

                $layouts[] = trim($layoutName);
            }
        }

        return $layouts;
    }

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

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

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

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

        return $layouts;
    }
}
