<?php
/**
* @package   Gridbox
* @author    Balbooa http://www.balbooa.com/
* @copyright Copyright @ Balbooa
* @license   http://www.gnu.org/licenses/gpl.html GNU/GPL
*/

namespace Balbooa\Component\Gridbox\Administrator\Helper;

use Joomla\CMS\Factory;

defined('_JEXEC') or die;

class SidebarHelper
{
    private static bool $loaded = false;

    protected static array $accessLevels;
    protected static object $sidebar;
    protected static object $customItems;
    
    public static string $path;

    public static function make()
    {
        if (self::$loaded) {
            return static::class;
        }

        $api = GridboxHelper::getGridboxApi('sidebar');
        $user = Factory::getUser();
        self::$accessLevels = $user->getAuthorisedViewLevels();
        self::$sidebar = !$api ? self::getDefault() : json_decode($api->key);
        self::$path = GridboxHelper::$path . '/tmpl/layouts/sidebar';
        self::$customItems = (object) [
            'root'=> []
        ];
        self::getCustomItems();
        self::$loaded = true;

        return static::class;
    }

    public static function renderCustomItems(array $items) :string
    {
        $str = '';
        foreach ($items as $item) {
            if (!SidebarHelper::checkAccess($item->access)) {
                continue;
            }
            $classname = 'custom-sidebar-item sortable-handle';
            $children = '';
            $context = '';
            if (isset(self::$customItems->{$item->key})) {
                $children = self::renderCustomItems(self::$customItems->{$item->key});
            }
            if (!empty($children)) {
                $classname .= ' sidebar-context-parent';
                $context = 'apps-group-' . $item->key;
            }
            $str .= self::renderItem(
                $item->key,
                $item->link,
                $item->icon,
                $item->title,
                $classname,
                false,
                children: $children,
                childClass: 'custom-sidebar-items',
                context: $context,
                target: $item->target ?? '_self'
            );
        }

        return $str;
    }

    public static function getCustomItems():void
    {
        $list = self::$customItems;
        foreach (self::$sidebar->items as $item) {
            $key = !is_numeric($item->parent) ? 'root' : $item->parent;
            if (!isset($list->{$key})) {
                $list->{$key} = [];
            }
            $list->{$key}[] = $item;
        }
    }

    public static function getCustomTree() :string
    {
        return self::renderCustomItems(self::$customItems->root);
    }

    public static function getCustomContextMenus() :string
    {
        include self::$path . '/custom-context-menus.php';
        /** @var string $html */

        return $html;
    }

    public static function renderItem(
        string $key = '',
        string $link = '',
        string $icon = '',
        string $title = '',
        string $classname = '',
        bool $system = true,
        bool $settings = true,
        string $html = '',
        string $children = '',
        string $childClass = '',
        string $context = '',
        string $target = '_self'
        ) :string
    {
        if (!SidebarHelper::checkAccess(self::$sidebar->access->{$key} ?? null)) {
            return '';
        }
        if ($system) {
            $classname .= ' ' . GridboxHelper::checkActive($key);
        }
        if (empty($icon)) {
            $icon = 'zmdi zmdi-folder';
        }

        include self::$path . '/link-item.php';
        /** @var string $out */

        return $out;
    }

    public static function getAccess(string $key)
    {
        return self::$sidebar->access->{$key} ?? null;
    }

    public static function checkAccess($access):bool
    {
        return !$access || in_array($access, self::$accessLevels);
    }

    public static function saveSidebar($data): void
    {
        $api = GridboxHelper::getGridboxApi('sidebar');
        $db = Factory::getDbo();
        $method = $api ? 'updateObject' : 'insertObject';
        if (!$api) {
            $api = (object)[
                'service' => 'sidebar'
            ];
        }
        $api->key = $data;
        $db->{$method}('#__gridbox_api', $api, 'id');
    }

    public static function getSidebar(): object
    {
        return self::$sidebar;
    }

    public static function getDefault(): object
    {
        return (object) [
            'access' => new \stdClass,
            'items' => []
        ];
    }
}