import {
  registerNavSection,
  registerNavItem,
  getNavSections,
  getNavItems,
} from './registry.js';
import { isDevkitEnabled } from '../../shared/lib/appConfig.js';
import { PERMISSIONS } from '@zen/core/users/constants';
// Side-effect : déclenche l'enregistrement nav du module Médias (gated par
// ZEN_MEDIA en interne). Importé en haut du fichier pour que les side effects
// s'exécutent lors du premier import du barrel admin.
import '../media/navigation.js';

// Sections et items core — enregistrés à l'import de ce module.
registerNavSection({ id: 'dashboard', title: 'Tableau de bord', icon: 'DashboardSquare03Icon', order: 10 });
registerNavSection({ id: 'system',    title: 'Utilisateurs',    icon: 'UserMultiple02Icon',     order: 800 });

registerNavItem({ id: 'dashboard', label: 'Tableau de bord', icon: 'DashboardSquare03Icon', href: '/admin/dashboard', sectionId: 'dashboard', order: 10 });
registerNavItem({ id: 'users',     label: 'Utilisateurs',   icon: 'UserMultiple02Icon',    href: '/admin/users',     sectionId: 'system',    order: 10, permission: PERMISSIONS.USERS_VIEW   });
registerNavItem({ id: 'roles',     label: 'Rôles',          icon: 'Crown03Icon',           href: '/admin/roles',     sectionId: 'system',    order: 20, permission: PERMISSIONS.ROLES_VIEW   });
registerNavItem({ id: 'settings',  label: 'Paramètres',     icon: 'Settings02Icon',        href: '/admin/settings',  position: 'bottom',     order: 10 });

if (isDevkitEnabled()) {
  registerNavSection({ id: 'devkit', title: 'DevKit', icon: 'Wrench01Icon', order: 900 });
  registerNavItem({ id: 'devkit-components', label: 'Composants', icon: 'Layers01Icon', href: '/admin/devkit/components', sectionId: 'devkit', order: 10 });
  registerNavItem({ id: 'devkit-icons', label: 'Icônes', icon: 'Image01Icon', href: '/admin/devkit/icons', sectionId: 'devkit', order: 20 });
}

/**
 * Zone d'appartenance d'un nav item — toute URL préfixée par ce path est
 * considérée comme « sous » l'item, même si elle ne correspond pas à `href`.
 *
 * Auto-déduction : un href du type `/admin/posts/blogue/list` couvre aussi
 * `/edit/:id` et `/new` du même parent — on retire `/list` pour obtenir le
 * basePath. Un module peut surcharger via `registerNavItem({ basePath })`.
 */
export function getNavItemBasePath(item) {
  if (item.basePath) return item.basePath;
  if (item.href.endsWith('/list')) return item.href.replace(/\/list$/, '');
  return item.href;
}

function matchLength(pathname, item) {
  if (pathname === item.href) return item.href.length;
  const basePath = getNavItemBasePath(item);
  if (pathname === basePath) return basePath.length;
  if (pathname.startsWith(basePath + '/')) return basePath.length;
  return 0;
}

/**
 * Sélectionne l'item « actif » pour un pathname donné parmi une liste d'items
 * (déjà filtrés par permission / position). Le match le plus long gagne :
 * sur `/admin/posts/blogue/taxonomies/categories`, l'item « Catégories »
 * (basePath complet) bat l'item « Posts » (basePath parent).
 */
function pickActiveItem(pathname, items) {
  let best = null;
  let bestLen = 0;
  for (const item of items) {
    const len = matchLength(pathname, item);
    if (len > bestLen) {
      best = item;
      bestLen = len;
    }
  }
  return best;
}

/**
 * Build sections for AdminSidebar. Items are sérialisables (pas de composants),
 * icônes en chaînes résolues côté client.
 * @param {string} pathname
 * @param {string[]} [userPermissions] - Permissions de l'utilisateur connecté ; les items
 *   avec un champ `permission` sont masqués si la permission n'est pas présente.
 */
export function buildNavigationSections(pathname, userPermissions = []) {
  const sections = getNavSections();
  const items = getNavItems().filter(item => {
    if (item.position === 'bottom') return false;
    if (item.permission && !userPermissions.includes(item.permission)) return false;
    return true;
  });

  const activeItem = pickActiveItem(pathname, items);

  const bySection = new Map();
  for (const item of items) {
    const list = bySection.get(item.sectionId) || [];
    list.push({
      name: item.label,
      href: item.href,
      basePath: getNavItemBasePath(item),
      icon: item.icon,
      current: item === activeItem,
    });
    bySection.set(item.sectionId, list);
  }

  return sections
    .filter(s => bySection.has(s.id))
    .map(s => ({ id: s.id, title: s.title, icon: s.icon, items: bySection.get(s.id) }));
}

/**
 * Build the list of bottom-pinned nav items for AdminSidebar.
 */
export function buildBottomNavItems(pathname) {
  const items = getNavItems()
    .filter(item => item.position === 'bottom')
    .sort((a, b) => (a.order ?? 0) - (b.order ?? 0));

  const activeItem = pickActiveItem(pathname, items);

  return items.map(item => ({
    name: item.label,
    href: item.href,
    basePath: getNavItemBasePath(item),
    icon: item.icon,
    current: item === activeItem,
  }));
}

/**
 * Localise dans `navigationSections` (forme retournée par `buildNavigationSections`)
 * l'item marqué comme actif et la section qui le contient. Utilisé par AdminTop
 * pour construire le fil d'Ariane à partir de la même source de vérité que la
 * sidebar — pas de double calcul de matching.
 *
 * Retourne `{ section, item, isExactPage, basePath }` ou `null`.
 *   - `isExactPage` : on est sur l'URL exacte du nav item (page liste / page racine).
 *      Permet de décider si l'item doit être cliquable dans le breadcrumb.
 *   - `basePath` : zone d'appartenance, sert à isoler le « trail » d'action
 *      (ex : `edit/1`, `new`) qui suit l'item dans le pathname.
 */
export function findActiveNavContext(pathname, navigationSections) {
  for (const section of navigationSections) {
    for (const item of section.items) {
      if (item.current) {
        return {
          section,
          item,
          isExactPage: pathname === item.href,
          basePath: item.basePath || item.href,
        };
      }
    }
  }
  return null;
}
