<?php
namespace Solwin\Verticalmenu\Block\Adminhtml\Menu;

class AbstractMenu extends \Magento\Backend\Block\Template
{
    /**
     * Core registry
     * 
     * @var \Magento\Framework\Registry
     */
    protected $coreRegistry;

    /**
     * Menu tree model instance
     * 
     * @var \Solwin\Verticalmenu\Model\ResourceModel\Menu\Tree
     */
    protected $menuTree;

    /**
     * Menu factory
     * 
     * @var \Solwin\Verticalmenu\Model\MenuFactory
     */
    protected $menuFactory;

    /**
     * Menu collection factory
     * 
     * @var \Solwin\Verticalmenu\Model\ResourceModel\Menu\CollectionFactory
     */
    protected $menuCollectionFactory;

    /**
     * constructor
     * 
     * @param \Magento\Framework\Registry $coreRegistry
     * @param \Solwin\Verticalmenu\Model\ResourceModel\Menu\Tree $menuTree
     * @param \Solwin\Verticalmenu\Model\MenuFactory $menuFactory
     * @param \Solwin\Verticalmenu\Model\ResourceModel\Menu\CollectionFactory $menuCollectionFactory
     * @param \Magento\Backend\Block\Widget\Context $context
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\Registry $coreRegistry,
        \Solwin\Verticalmenu\Model\ResourceModel\Menu\Tree $menuTree,
        \Solwin\Verticalmenu\Model\MenuFactory $menuFactory,
        \Solwin\Verticalmenu\Model\ResourceModel\Menu\CollectionFactory $menuCollectionFactory,
        \Magento\Backend\Block\Widget\Context $context,
        array $data = []
    )
    {
        $this->coreRegistry          = $coreRegistry;
        $this->menuTree              = $menuTree;
        $this->menuFactory           = $menuFactory;
        $this->menuCollectionFactory = $menuCollectionFactory;
        parent::__construct($context, $data);
    }

    /**
     * Retrieve current Menu instance
     *
     * @return \Solwin\Verticalmenu\Model\Menu
     */
    public function getMenu()
    {
        return $this->coreRegistry->registry('solwin_verticalmenu_menu');
    }

    /**
     * @return int|string|null
     */
    public function getMenuId()
    {
        if ($this->getMenu()) {
            return $this->getMenu()->getId();
        }
        return \Solwin\Verticalmenu\Model\Menu::TREE_ROOT_ID;
    }

    /**
     * @return string
     */
    public function getMenuMenu_title()
    {
        return $this->getMenu()->getMenu_title();
    }

    /**
     * @return mixed
     */
    public function getMenuPath()
    {
        if ($this->getMenu()) {
            return $this->getMenu()->getPath();
        }
        return \Solwin\Verticalmenu\Model\Menu::TREE_ROOT_ID;
    }


    /**
     * @param null $parentNodeMenu
     * @param int $recursionLevel
     * @return Node|mixed
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     */
    public function getRoot($parentNodeMenu = null, $recursionLevel = 3)
    {
        if ($parentNodeMenu !== null && $parentNodeMenu->getId()) {
            return $this->getNode($parentNodeMenu, $recursionLevel);
        }
        $root = $this->coreRegistry->registry('solwin_verticalmenu_menu_root');
        if ($root === null) {
            $rootId = \Solwin\Verticalmenu\Model\Menu::TREE_ROOT_ID;

            $tree = $this->menuTree->load(null, $recursionLevel);

            if ($this->getMenu()) {
                $tree->loadEnsuredNodes($this->getMenu(), $tree->getNodeById($rootId));
            }

            $tree->addCollectionData($this->getMenuCollection());

            $root = $tree->getNodeById($rootId);

            if ($root && $rootId != \Solwin\Verticalmenu\Model\Menu::TREE_ROOT_ID) {
                $root->setIsVisible(true);
            } elseif ($root && $root->getId() == \Solwin\Verticalmenu\Model\Menu::TREE_ROOT_ID) {
                $root->setName(__('ROOT'));
            }

            $this->coreRegistry->register('solwin_verticalmenu_menu_root', $root);
        }

        return $root;
    }

    /**
     * @return \Solwin\Verticalmenu\Model\ResourceModel\Menu\Collection
     */
    public function getMenuCollection()
    {
        $collection = $this->getData('menu_collection');
        if ($collection === null) {
            $collection = $this->menuCollectionFactory->create();
            $this->setData('menu_collection', $collection);
        }
        return $collection;
    }

    /**
     * Get and register Menus root by specified Menus IDs
     *
     * IDs can be arbitrary set of any Menus ids.
     * Tree with minimal required nodes (all parents and neighbours) will be built.
     * If ids are empty, default tree with depth = 2 will be returned.
     *
     * @param array $ids
     * @return mixed
     */
    public function getRootByIds($ids)
    {
        $root = $this->coreRegistry->registry('solwin_verticalmenu_menu_root');
        if (null === $root) {
            $ids = $this->menuTree->getExistingMenuIdsBySpecifiedIds($ids);
            $tree = $this->menuTree->loadByIds($ids);
            $rootId = \Solwin\Verticalmenu\Model\Menu::TREE_ROOT_ID;
            $root = $tree->getNodeById($rootId);
            if ($root && $rootId != \Solwin\Verticalmenu\Model\Menu::TREE_ROOT_ID) {
                $root->setIsVisible(true);
            } elseif ($root && $root->getId() == \Solwin\Verticalmenu\Model\Menu::TREE_ROOT_ID) {
                $root->setName(__('Root'));
            }

            $tree->addCollectionData($this->getMenuCollection());
            $this->coreRegistry->register('solwin_verticalmenu_menu_root', $root);
        }
        return $root;
    }

    /**
     * @param $parentNodeMenu
     * @param int $recursionLevel
     * @return Node
     */
    public function getNode($parentNodeMenu, $recursionLevel = 2)
    {
        $nodeId = $parentNodeMenu->getId();
        $node = $this->menuTree->loadNode($nodeId);
        $node->loadChildren($recursionLevel);

        if ($node && $nodeId != \Solwin\Verticalmenu\Model\Menu::TREE_ROOT_ID) {
            $node->setIsVisible(true);
        } elseif ($node && $node->getId() == \Solwin\Verticalmenu\Model\Menu::TREE_ROOT_ID) {
            $node->setName(__('Root'));
        }

        $this->menuTree->addCollectionData($this->getMenuCollection());

        return $node;
    }

    /**
     * @param array $args
     * @return string
     */
    public function getSaveUrl(array $args = [])
    {
        $params = ['_current' => false, '_query' => false];
        $params = array_merge($params, $args);
        return $this->getUrl('solwin_verticalmenu/*/save', $params);
    }

    /**
     * @return string
     */
    public function getEditUrl()
    {
        return $this->getUrl(
            'solwin_verticalmenu/menu/edit',
            ['_query' => false, 'id' => null, 'parent' => null]
        );
    }
    /**
     * @return []
     */
    public function getRootIds()
    {
        return [\Solwin\Verticalmenu\Model\Menu::TREE_ROOT_ID];
    }
}
