<?php

namespace WordpressModels\Page;

/**
 * Extension of the Page class to provide client-side routing with the WordPress admin menu.
 *
 * Make sure your route exists in your client application.
 *
 * For example, when using react and react-router:
 *
 * Your 'main' page: 'admin.php?page=your-page' (aliased as 'admin.php?page=your-page#/')
 *
 * Somewhere in your plugin:
 * ```php
 *   ...
 *  $mainPage = new YourMainPage(...);
 *  $mainPage->addRoute(new YourSubPage(...));
 * ```
 *
 * Your 'sub' page will now be: 'admin.php?page=your-page#/your-sub-page'
 */
abstract class AbstractPageStack extends AbstractPage
{

    /**
     * @var AbstractPage[]
     */
    protected array $pages = [];

    public function getRouteUrl(string $route)
    {
        return get_admin_url(path: "admin.php?page=$this->menuSlug&path=/$route");
    }

    /**
     * @param AbstractPage $page
     * @return void
     */
    public function addRoute(AbstractPage $page, bool $isSubPage = true): void
    {
        $this->pages[] = $page;
        // set the menu slug to the route url
        $page->menuSlug = $this->getRouteUrl($page->pageId);

        // add all additional scripts to the stack
        $this->additionalScripts = [
            ...$this->additionalScripts,
            ...$page->additionalScripts
        ];

        // set the parent to the main page if it is a sub page
        if ($isSubPage) {
            $page->parent = $this->menuSlug;
        }

        // clear the render callback, such that wordpress sets the url of the admin item to the route url
        $page->renderCallback = '';
    }

    public function doEnqueue()
    {
        wp_localize_script($this->pageId, 'pages', array_reduce(
            $this->pages,
            function (array $carry, AbstractPage $page) {
                if (current_user_can($page->capability)) {
                    $carry[] = $page->pageId;
                }
                return $carry;
            }, []));
    }
}
