<?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 YOOtheme\Arr;
use YOOtheme\Config;
use YOOtheme\File;
use YOOtheme\Http\Request;
use YOOtheme\Http\Response;
use YOOtheme\Path;

class LayoutsController
{
    /**
     * @var Layouts
     */
    public $layouts;

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

    /**
     * @var array
     */
    public $ubications;

    /**
     * Constructor.
     */
    public function __construct(Layouts $layouts, Config $config)
    {
        $this->layouts = $layouts;
        $this->config = $config;

        $this->ubications = array_map(function ($ubicaction) {
            return Path::resolveAlias($ubicaction);
        }, $this->layouts->typesUbications);
    }

    public function getLayouts(Request $request, Response $response)
    {
        try {
            $offset = (int) $request->getParam('offset', 0);
            $length = (int) $request->getParam('length', 200);
            $search = $request->getParam('search');
            $group = $request->getParam('group');
            $type = $request->getParam('type');

            $ubications = $type === 'mylayouts'
                ? [$this->config->get('theme.childDir')]
                : $this->ubications;

            $result = $this->fetchLayouts($ubications, $offset, $length, $search, $type, $group);

            return $response->withJson($result);
        } catch (\Exception $e) {
            $request->abort(400, $e->getMessage());
        }
    }

    public function getTypes(Request $request, Response $response)
    {
        try {
            $result = array_map(function ($type) {
                return [
                    'name' => $type->name(),
                    'title' => str_replace('_',' ',$type->title()),
                    'groups' => $type->groups()
                ];
            }, array_values($this->fetchTypes()));

            return $response->withJson($result);
        } catch (\Exception $e) {
            $request->abort(400, $e->getMessage());
        }
    }

    protected function fetchTypes()
    {
        static $types = [];

        if (empty($types)) {

            foreach ($this->ubications as $dir) {
                $paths = Arr::filter(File::glob("{$dir}/*"), [File::class, 'isDir']);

                foreach ($paths as $path) {
                    $name = basename($path);

                    if (!isset($types[$name])) {
                        $types[$name] = new Type($path);
                    }
                }
            }
        }

        return array_values($types);
    }

    protected function fetchLayouts($ubications, $offset, $length, $search = null, $type = null, $group = null)
    {
        $types = array_map(function ($type) {
            return $type->name();
        }, $this->fetchTypes());

        $namePattern = $search ? "*$search*" : '*';
        $typePattern = $type ? "/$type/" : '/*/';
        $groupPattern = $group === '__main' ? '' : ($group ? "$group/" : '{,*/}');

        $pattern = '{' . implode(',', $ubications) . '}' . $typePattern . $groupPattern . "$namePattern.json";

        $layouts = File::glob($pattern);
        $total = count($layouts);
        $layouts = array_splice($layouts, $offset, $length);

        $data = new \stdClass;

        foreach ($layouts as $path) {
            $type = basename(dirname(dirname($path)));

            if (!in_array($type, $types)) {
                $type = $group;
                $group = null;
            }

            $layout = basename($path, '.json');
            $content = File::getContents($path);

            $key = $group
                ? sprintf('%s-%s--%s', $type, $group, $layout)
                : sprintf('%s--%s', $type, $layout);

            $data->$key = json_decode($content);
        }

        return compact('data', 'total', 'offset', 'length', 'search', 'type', 'group');
    }
}
