<?php

declare(strict_types=1);

require_once dirname(__DIR__, 3) . '/system/bootstrap.php';

$requestPath = myronResolveAppRequestPath((string) ($_SERVER['REQUEST_URI'] ?? ''));
if ($requestPath === '/content/menus') {
    myronRedirect(myronBuildAdminUrl('administration.menus', $_GET));
}

$currentUser = myronRequireAdministrationAccess();
$repository = myronContentRepository();
$csrfToken = myronCsrfToken();
$view = trim((string) ($_GET['view'] ?? 'edit')) === 'locations' ? 'locations' : 'edit';
$requestedMenuId = trim((string) ($_GET['menu'] ?? ''));
$showCreateForm = trim((string) ($_GET['create'] ?? '')) === '1';

/**
 * @param array<string, scalar|null> $params
 */
function myronMenuManagerUrl(array $params = []): string
{
    $base = myronBuildAdminUrl('administration.menus');
    $normalized = [];

    foreach ($params as $key => $value) {
        if ($value === null) {
            continue;
        }

        $stringValue = trim((string) $value);
        if ($stringValue === '') {
            continue;
        }

        $normalized[$key] = $stringValue;
    }

    return $normalized === [] ? $base : $base . '?' . http_build_query($normalized);
}

if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
    try {
        myronRequireCsrf($_POST['csrf_token'] ?? null);
        $action = trim((string) ($_POST['action'] ?? ''));
        $postedMenuId = trim((string) ($_POST['menu_id'] ?? ''));

        if ($action === 'create-menu') {
            $menu = $repository->createMenu(trim((string) ($_POST['menu_name'] ?? '')));
            myronRedirectWithFlash(myronMenuManagerUrl([
                'view' => 'edit',
                'menu' => (string) ($menu['id'] ?? ''),
            ]), 'Created new menu.', 'success');
        }

        if ($action === 'save-placement-assignments') {
            $repository->updatePlacementAssignments(is_array($_POST['placements'] ?? null) ? $_POST['placements'] : []);
            myronRedirectWithFlash(myronMenuManagerUrl([
                'view' => 'locations',
            ]), 'Updated menu placements.', 'success');
        }

        if ($action === 'add-to-menu') {
            $repository->addPageToMenu(
                $postedMenuId,
                trim((string) ($_POST['page_id'] ?? '')),
                trim((string) ($_POST['menu_label'] ?? ''))
            );
            myronRedirectWithFlash(myronMenuManagerUrl([
                'view' => 'edit',
                'menu' => $postedMenuId,
            ]), 'Added page to menu.', 'success');
        }

        if ($action === 'remove-menu-item') {
            $repository->removeMenuItem(trim((string) ($_POST['menu_item_id'] ?? '')));
            myronRedirectWithFlash(myronMenuManagerUrl([
                'view' => 'edit',
                'menu' => $postedMenuId,
            ]), 'Removed menu item.', 'success');
        }

        if ($action === 'move-menu-item') {
            $repository->moveMenuItem(
                $postedMenuId,
                trim((string) ($_POST['menu_item_id'] ?? '')),
                is_string($_POST['parent_menu_item_id'] ?? null) ? (string) $_POST['parent_menu_item_id'] : null,
                is_string($_POST['after_menu_item_id'] ?? null) ? (string) $_POST['after_menu_item_id'] : null
            );
            myronRedirectWithFlash(myronMenuManagerUrl([
                'view' => 'edit',
                'menu' => $postedMenuId,
            ]), 'Updated menu order.', 'success');
        }

        throw new RuntimeException('Unknown menu manager action.');
    } catch (Throwable $exception) {
        myronRedirectWithFlash(myronMenuManagerUrl([
            'view' => $view,
            'menu' => $requestedMenuId,
            'create' => $showCreateForm ? '1' : '',
        ]), $exception->getMessage(), 'error');
    }
}

$menus = $repository->listMenusWithItems();
$placements = $repository->listMenuPlacements();
$pages = $repository->listPagesForManager();

$selectedMenu = null;
if ($requestedMenuId !== '') {
    foreach ($menus as $menu) {
        if ((string) ($menu['id'] ?? '') === $requestedMenuId) {
            $selectedMenu = $menu;
            break;
        }
    }
}
if ($selectedMenu === null && $menus !== []) {
    $selectedMenu = $menus[0];
}

$selectedMenuId = (string) ($selectedMenu['id'] ?? '');
$selectedMenuPageIds = [];
if ($selectedMenu !== null) {
    $flattenedSelectedItems = [];
    $walkItems = static function (array $items) use (&$walkItems, &$flattenedSelectedItems): void {
        foreach ($items as $item) {
            if (!is_array($item)) {
                continue;
            }

            $flattenedSelectedItems[] = $item;
            $children = $item['children'] ?? [];
            if (is_array($children) && $children !== []) {
                $walkItems($children);
            }
        }
    };
    $walkItems(is_array($selectedMenu['items'] ?? null) ? $selectedMenu['items'] : []);
    foreach ($flattenedSelectedItems as $item) {
        $selectedMenuPageIds[(string) ($item['page_id'] ?? '')] = true;
    }
}

$childrenByParent = [];
$rootPages = [];
foreach ($pages as $page) {
    $parentId = trim((string) ($page['parent_page_id'] ?? ''));
    if ($parentId === '') {
        $rootPages[] = $page;
        continue;
    }

    $childrenByParent[$parentId][] = $page;
}

$searchPages = $pages;
usort(
    $searchPages,
    static fn (array $left, array $right): int => strcasecmp((string) ($left['title'] ?? ''), (string) ($right['title'] ?? ''))
);

/**
 * @param array<string, bool> $selectedMenuPageIds
 */
function myronRenderMenuBrowserAction(array $page, string $selectedMenuId, string $csrfToken, array $selectedMenuPageIds): void
{
    $pageId = (string) ($page['id'] ?? '');
    $alreadyAdded = isset($selectedMenuPageIds[$pageId]);
    ?>
    <div class="mc-menu-browser__actions">
      <?php if ($alreadyAdded): ?>
      <span class="sg-pill sg-pill--active">Already in menu</span>
      <?php elseif ($selectedMenuId !== ''): ?>
      <form method="post" class="sg-inline-form">
        <input type="hidden" name="csrf_token" value="<?= myronEscape($csrfToken) ?>">
        <input type="hidden" name="action" value="add-to-menu">
        <input type="hidden" name="view" value="edit">
        <input type="hidden" name="menu_id" value="<?= myronEscape($selectedMenuId) ?>">
        <input type="hidden" name="page_id" value="<?= myronEscape($pageId) ?>">
        <button class="sg-button sg-button--secondary" type="submit">Add</button>
      </form>
      <?php else: ?>
      <span class="sg-pill">Select a menu first</span>
      <?php endif; ?>
    </div>
    <?php
}

/**
 * @param list<array<string, mixed>> $pages
 * @param array<string, list<array<string, mixed>>> $childrenByParent
 * @param array<string, bool> $selectedMenuPageIds
 */
function myronRenderMenuBrowserTree(array $pages, array $childrenByParent, string $selectedMenuId, string $csrfToken, array $selectedMenuPageIds): void
{
    foreach ($pages as $page) {
        $pageId = (string) ($page['id'] ?? '');
        $children = $childrenByParent[$pageId] ?? [];
        $meta = [];
        $meta[] = (string) ($page['path'] ?? '/');
        $meta[] = trim((string) ($page['template_name'] ?? '')) !== '' ? (string) $page['template_name'] : 'Template pending';
        $versionNumber = $page['manager_version_number'] ?? null;
        if ($versionNumber !== null && (int) $versionNumber > 0) {
            $meta[] = 'v' . (string) $versionNumber;
        }
        $meta[] = ucfirst((string) ($page['publication_state'] ?? 'draft'));

        if ($children !== []) {
            ?>
            <details class="mc-menu-browser-branch" open>
              <summary class="mc-menu-browser-branch__summary">
                <span class="mc-menu-browser-branch__title"><?= myronEscape((string) ($page['title'] ?? 'Untitled')) ?></span>
                <span class="mc-menu-browser-branch__meta"><?= myronEscape(implode(' · ', $meta)) ?></span>
              </summary>
              <div class="mc-menu-browser-branch__body">
                <?php myronRenderMenuBrowserAction($page, $selectedMenuId, $csrfToken, $selectedMenuPageIds); ?>
                <div class="mc-menu-browser-tree__children">
                  <?php myronRenderMenuBrowserTree($children, $childrenByParent, $selectedMenuId, $csrfToken, $selectedMenuPageIds); ?>
                </div>
              </div>
            </details>
            <?php
            continue;
        }
        ?>
        <div class="mc-menu-browser-row">
          <div>
            <div class="mc-menu-browser-row__title"><?= myronEscape((string) ($page['title'] ?? 'Untitled')) ?></div>
            <div class="mc-menu-browser-row__meta"><?= myronEscape(implode(' · ', $meta)) ?></div>
          </div>
          <?php myronRenderMenuBrowserAction($page, $selectedMenuId, $csrfToken, $selectedMenuPageIds); ?>
        </div>
        <?php
    }
}

/**
 * @param list<array<string, mixed>> $items
 */
function myronRenderMenuItems(array $items, string $menuId, string $csrfToken, int $depth, ?string $parentId = null): void
{
    ?>
    <div class="mc-menu-drop-target" data-menu-id="<?= myronEscape($menuId) ?>" data-parent-menu-item-id="<?= myronEscape((string) ($parentId ?? '')) ?>" data-after-menu-item-id="">
      Drop here
    </div>
    <?php foreach ($items as $item): ?>
    <?php
      $state = ucfirst((string) ($item['publication_state'] ?? 'draft'));
      $versionNumber = $item['manager_version_number'] ?? null;
      $metaParts = [
          (string) ($item['page_path'] ?? '/'),
          trim((string) ($item['template_name'] ?? '')) !== '' ? (string) $item['template_name'] : 'Template pending',
          $versionNumber !== null && (int) $versionNumber > 0 ? 'v' . (string) $versionNumber : 'v-',
          $state,
      ];
      $label = trim((string) ($item['label'] ?? ''));
      $pageTitle = trim((string) ($item['page_title'] ?? ''));
      $isPublished = (string) ($item['publication_state'] ?? 'draft') === 'published';
      $depthClass = 'mc-menu-node__row--depth-' . (string) min(max(0, $depth), 6);
    ?>
    <div class="mc-menu-node">
      <div class="mc-menu-node__row <?= myronEscape($depthClass) ?>" draggable="true" data-menu-draggable data-menu-id="<?= myronEscape($menuId) ?>" data-menu-item-id="<?= myronEscape((string) $item['id']) ?>">
        <div class="mc-menu-node__main">
          <span class="mc-menu-node__handle" aria-hidden="true">&#8942;&#8942;</span>
          <div class="mc-menu-node__content">
            <strong class="mc-menu-node__title"><?= myronEscape($label) ?></strong>
            <?php if ($pageTitle !== '' && $pageTitle !== $label): ?>
            <div class="mc-menu-node__context">Page title: <?= myronEscape($pageTitle) ?></div>
            <?php endif; ?>
            <div class="mc-menu-node__meta"><?= myronEscape(implode(' · ', $metaParts)) ?></div>
          </div>
        </div>
        <div class="mc-menu-node__actions">
          <a class="sg-button sg-button--secondary" href="<?= myronEscape(myronBuildAdminUrl('content.pageEditor')) ?>?page=<?= rawurlencode((string) $item['page_id']) ?>">Edit Page</a>
          <?php if ($isPublished): ?>
          <a class="sg-button sg-button--secondary" href="<?= myronEscape((string) ($item['preview_url'] ?? '#')) ?>" target="_blank" rel="noreferrer">View Live</a>
          <?php endif; ?>
          <form method="post" class="sg-inline-form">
            <input type="hidden" name="csrf_token" value="<?= myronEscape($csrfToken) ?>">
            <input type="hidden" name="action" value="remove-menu-item">
            <input type="hidden" name="view" value="edit">
            <input type="hidden" name="menu_id" value="<?= myronEscape($menuId) ?>">
            <input type="hidden" name="menu_item_id" value="<?= myronEscape((string) $item['id']) ?>">
            <button class="sg-button sg-button--danger" type="submit">Remove</button>
          </form>
        </div>
      </div>

      <?php
      $children = $item['children'] ?? [];
      if (is_array($children) && $children !== []) {
          myronRenderMenuItems($children, $menuId, $csrfToken, $depth + 1, (string) $item['id']);
      }
      ?>

      <div class="mc-menu-drop-target" data-menu-id="<?= myronEscape($menuId) ?>" data-parent-menu-item-id="<?= myronEscape((string) ($parentId ?? '')) ?>" data-after-menu-item-id="<?= myronEscape((string) $item['id']) ?>">
        Drop after
      </div>
    </div>
    <?php endforeach; ?>
    <?php
}

myronRenderAdminShellStart($currentUser, [
    'title' => 'Menu Manager',
    'titleContext' => 'Administration',
    'activeItem' => 'menus',
    'headScripts' => [myronBuildAssetUrl('runtime/js/menu-manager.js')],
]);
?>
<div class="mc-workspace__header">
  <?php myronRenderAdminBreadcrumbs([
      ['label' => 'Administration', 'href' => myronBuildAdminUrl('identity.users')],
      ['label' => 'Manage', 'href' => myronBuildAdminUrl('identity.users')],
      ['label' => 'Menus'],
  ]); ?>
  <div class="mc-workspace__title-row mc-workspace__title-row--actions">
    <h1 class="mc-workspace__title">Menus</h1>
    <div class="mc-workspace__actions">
      <a class="sg-button sg-button--secondary" href="<?= myronEscape(myronBuildAdminUrl('content.pages')) ?>">Back to Pages</a>
    </div>
  </div>
  <p class="mc-workspace__subtitle">Select a menu to edit, assign placements to selected menus, and build nested navigation from your published structure.</p>
</div>

<div class="mc-page-canvas mc-page-canvas--site">
  <div class="sg-main">
    <form method="post" id="mc-menu-move-form" class="mc-visually-hidden">
      <input type="hidden" name="csrf_token" value="<?= myronEscape($csrfToken) ?>">
      <input type="hidden" name="action" value="move-menu-item">
      <input type="hidden" name="view" value="edit">
      <input type="hidden" name="menu_id" value="<?= myronEscape($selectedMenuId) ?>">
      <input type="hidden" name="menu_item_id" value="">
      <input type="hidden" name="parent_menu_item_id" value="">
      <input type="hidden" name="after_menu_item_id" value="">
    </form>

    <div class="mc-menu-screen">
      <nav class="mc-menu-tabs" aria-label="Menu manager views">
        <a class="mc-menu-tab<?= $view === 'edit' ? ' mc-menu-tab--active' : '' ?>" href="<?= myronEscape(myronMenuManagerUrl(['view' => 'edit', 'menu' => $selectedMenuId])) ?>"<?= $view === 'edit' ? ' aria-current="page"' : '' ?>>Edit Menus</a>
        <a class="mc-menu-tab<?= $view === 'locations' ? ' mc-menu-tab--active' : '' ?>" href="<?= myronEscape(myronMenuManagerUrl(['view' => 'locations', 'menu' => $selectedMenuId])) ?>"<?= $view === 'locations' ? ' aria-current="page"' : '' ?>>Manage Locations</a>
      </nav>

      <?php if ($view === 'locations'): ?>
      <section class="sg-section">
        <div class="mc-menu-panel__header">
          <div>
            <h2 class="sg-section__title">Manage Locations</h2>
            <p class="sg-section__subtitle">Placements point to the selected menus that should render on the public site.</p>
          </div>
        </div>

        <form method="post" class="sg-form-grid">
          <input type="hidden" name="csrf_token" value="<?= myronEscape($csrfToken) ?>">
          <input type="hidden" name="action" value="save-placement-assignments">
          <input type="hidden" name="view" value="locations">

          <?php foreach ($placements as $placement): ?>
          <label class="sg-field">
            <span class="sg-field__label"><?= myronEscape((string) ($placement['label'] ?? 'Placement')) ?></span>
            <select class="sg-field__control" name="placements[<?= myronEscape((string) ($placement['placement_key'] ?? '')) ?>]">
              <option value="">No menu assigned</option>
              <?php foreach ($menus as $menu): ?>
              <option value="<?= myronEscape((string) $menu['id']) ?>"<?= (string) ($placement['menu_id'] ?? '') === (string) ($menu['id'] ?? '') ? ' selected' : '' ?>>
                <?= myronEscape((string) ($menu['name'] ?? 'Untitled Menu')) ?>
              </option>
              <?php endforeach; ?>
            </select>
          </label>
          <?php endforeach; ?>

          <div class="sg-card__actions">
            <button class="sg-button sg-button--primary" type="submit">Save Placement Assignments</button>
          </div>
        </form>
      </section>
      <?php else: ?>
      <section class="sg-section">
        <div class="mc-menu-selector">
          <form method="get" class="mc-menu-selector__form">
            <input type="hidden" name="view" value="edit">
            <label class="sg-field mc-menu-selector__field">
              <span class="sg-field__label">Select a menu to edit</span>
              <select class="sg-field__control" name="menu">
                <?php foreach ($menus as $menu): ?>
                <option value="<?= myronEscape((string) $menu['id']) ?>"<?= (string) ($menu['id'] ?? '') === $selectedMenuId ? ' selected' : '' ?>>
                  <?= myronEscape((string) ($menu['name'] ?? 'Untitled Menu')) ?>
                </option>
                <?php endforeach; ?>
              </select>
            </label>
            <button class="sg-button sg-button--secondary" type="submit">Select</button>
          </form>
          <a class="mc-menu-selector__create-link" href="<?= myronEscape(myronMenuManagerUrl(['view' => 'edit', 'menu' => $selectedMenuId, 'create' => '1'])) ?>">Create a new menu</a>
        </div>
      </section>

      <?php if ($showCreateForm || $menus === []): ?>
      <section class="sg-section">
        <div class="mc-menu-panel__header">
          <div>
            <h2 class="sg-section__title">Create Menu</h2>
            <p class="sg-section__subtitle">Add a named menu to the registry, then assign it to a placement when you are ready to publish it.</p>
          </div>
        </div>
        <form method="post" class="sg-form-grid">
          <input type="hidden" name="csrf_token" value="<?= myronEscape($csrfToken) ?>">
          <input type="hidden" name="action" value="create-menu">
          <label class="sg-field">
            <span class="sg-field__label">Menu Name</span>
            <input class="sg-field__control" type="text" name="menu_name" placeholder="Primary Navigation" required>
          </label>
          <div class="sg-card__actions">
            <button class="sg-button sg-button--primary" type="submit">Create Menu</button>
          </div>
        </form>
      </section>
      <?php endif; ?>

      <?php if ($selectedMenu !== null): ?>
      <section class="sg-section">
        <div class="mc-menu-panel__header">
          <div>
            <h2 class="sg-section__title"><?= myronEscape((string) ($selectedMenu['name'] ?? 'Untitled Menu')) ?></h2>
            <p class="sg-section__subtitle"><?= myronEscape((string) ($selectedMenu['placement_label'] ?? 'Unassigned')) ?></p>
          </div>
        </div>

        <div class="mc-menu-workbench">
          <div class="mc-menu-tree-panel">
            <div class="mc-menu-tree-panel__header">
              <div>
                <h3 class="sg-section__title sg-section__title--sm">Menu Structure</h3>
                <p class="sg-section__subtitle">Drag menu items to reorder or nest them. Each row keeps the page path, template, version, and publication state visible.</p>
              </div>
            </div>

            <div class="mc-menu-tree">
              <?php if (($selectedMenu['items'] ?? []) === []): ?>
              <div class="mc-menu-empty-state">This menu is empty. Add pages from the browser to start building navigation.</div>
              <?php else: ?>
              <?php myronRenderMenuItems(is_array($selectedMenu['items'] ?? null) ? $selectedMenu['items'] : [], $selectedMenuId, $csrfToken, 0); ?>
              <?php endif; ?>
            </div>
          </div>

          <aside class="mc-menu-browser-panel">
            <div class="mc-menu-browser-panel__header">
              <div>
                <h3 class="sg-section__title sg-section__title--sm">Add Menu Items</h3>
                <p class="sg-section__subtitle">Browse the page tree, collapse branches, or search titles and paths to add pages into the selected menu.</p>
              </div>
            </div>

            <label class="sg-field">
              <span class="sg-field__label">Search Pages</span>
              <input class="sg-field__control" type="search" placeholder="Search title or path" data-menu-page-search>
            </label>

            <div class="mc-menu-browser" data-menu-browser-root>
              <div class="mc-menu-browser__tree" data-menu-browser-tree>
                <?php myronRenderMenuBrowserTree($rootPages, $childrenByParent, $selectedMenuId, $csrfToken, $selectedMenuPageIds); ?>
              </div>

              <div class="mc-menu-browser__results" data-menu-browser-results hidden>
                <?php foreach ($searchPages as $page): ?>
                <?php
                  $pageMeta = [
                      (string) ($page['path'] ?? '/'),
                      trim((string) ($page['template_name'] ?? '')) !== '' ? (string) $page['template_name'] : 'Template pending',
                      isset($page['manager_version_number']) && (int) $page['manager_version_number'] > 0 ? 'v' . (string) $page['manager_version_number'] : 'v-',
                      ucfirst((string) ($page['publication_state'] ?? 'draft')),
                  ];
                  $searchText = strtolower(
                      trim((string) ($page['title'] ?? '')) . ' ' .
                      trim((string) ($page['path'] ?? '')) . ' ' .
                      trim((string) ($page['slug'] ?? ''))
                  );
                ?>
                <div class="mc-menu-browser-row" data-menu-browser-result data-search-text="<?= myronEscape($searchText) ?>">
                  <div>
                    <div class="mc-menu-browser-row__title"><?= myronEscape((string) ($page['title'] ?? 'Untitled')) ?></div>
                    <div class="mc-menu-browser-row__meta"><?= myronEscape(implode(' · ', $pageMeta)) ?></div>
                  </div>
                  <?php myronRenderMenuBrowserAction($page, $selectedMenuId, $csrfToken, $selectedMenuPageIds); ?>
                </div>
                <?php endforeach; ?>
                <div class="mc-menu-browser__empty" data-menu-browser-empty hidden>No pages match the current search.</div>
              </div>
            </div>
          </aside>
        </div>
      </section>
      <?php else: ?>
      <section class="sg-section">
        <div class="mc-menu-empty-state">Create a menu to begin managing placements and nested navigation.</div>
      </section>
      <?php endif; ?>
      <?php endif; ?>
    </div>
  </div>
</div>
<?php myronRenderAdminShellEnd(); ?>
