import {
  BadgeDollarSign,
  Calculator,
  ClipboardPenLine,
  FlaskConical,
  Gauge,
  Layers,
  LayoutDashboard,
  Link2,
  ListOrdered,
  Package,
  Plug,
  ShieldCheck,
  ShoppingCart,
  SlidersHorizontal,
  Settings,
  Tags,
  TrendingUp,
  Users
} from 'lucide-svelte';
import type { ComponentType } from 'svelte';

import { featureFlags } from '$lib/features';
import {
  canOpenDashboard
} from '$lib/workspace-access';
import type { AppSession } from '$lib/session';

export type SearchItem = {
  href: string;
  label: string;
  description: string;
  keywords: string;
};

export type NavItem = {
  href: string;
  label: string;
  shortLabel: string;
  icon: ComponentType;
  moduleKey?: string;
  badge?: string;
  /**
   * Highlight this row only on an exact pathname match instead of a prefix
   * match. Needed for parent routes like `/ordering/manage` that are a prefix
   * of their siblings (`/ordering/manage/products`).
   */
  exact?: boolean;
  /**
   * Optional third-level submenu. A child with `children` renders as its own
   * collapsible row inside a group (e.g. Integrations → Xero). The row stays a
   * link to its own `href`; a chevron toggles the nested list.
   */
  children?: NavItem[];
};

export type FooterLink = {
  href: string;
  label: string;
  shortLabel: string;
  icon: ComponentType;
};

/**
 * A collapsible family of related modules in the primary rail. Groups keep the
 * top level short as more modules ship: a new costing tool becomes another child
 * here rather than another peer in a flat stack.
 */
export type NavGroup = {
  id: string;
  label: string;
  icon: ComponentType;
  children: NavItem[];
  /**
   * When set, the group header is itself a link (clicking it navigates here)
   * while a separate chevron still toggles the child list. Used by Order
   * Management: clicking the header lands on the order queue.
   */
  href?: string;
  /** Exact-match the header link's active state (see NavItem.exact). */
  exact?: boolean;
};

/** The rail is a sequence of standalone items and collapsible groups. */
export type NavEntry =
  | { kind: 'item'; item: NavItem }
  | { kind: 'group'; group: NavGroup };

export type Crumb = {
  label: string;
  href?: string;
};

export type PageMeta = {
  title: string;
  category: string;
  icon: ComponentType;
};

export const dashboardItem: NavItem = {
  href: '/',
  label: 'Dashboard',
  shortLabel: 'DB',
  icon: LayoutDashboard,
  moduleKey: 'dashboard'
};

export const mixCalculatorItem: NavItem = {
  href: '/mix-calculator',
  label: 'Mix Calculator',
  shortLabel: 'MC',
  icon: Calculator,
  moduleKey: 'mix_calculator'
};

export const productCostingItem: NavItem = {
  href: '/product-costing',
  label: 'Product Costing',
  shortLabel: 'PC',
  icon: BadgeDollarSign,
  moduleKey: 'products',
  badge: 'Alpha'
};

export const editorItem: NavItem = {
  href: '/editor',
  label: 'Mix Editor',
  shortLabel: 'ED',
  icon: ClipboardPenLine,
  moduleKey: 'products',
  badge: 'test'
};

export const ingredientsEditorItem: NavItem = {
  href: '/ingredients',
  label: 'Ingredients Editor',
  shortLabel: 'IE',
  icon: FlaskConical,
  moduleKey: 'products',
  badge: 'test'
};

export const reportingItem: NavItem = {
  href: '/reporting',
  label: 'Reporting',
  shortLabel: 'RP',
  icon: TrendingUp,
  moduleKey: 'products'
};

export const throughputItem: NavItem = {
  href: '/throughput',
  label: 'Throughput',
  shortLabel: 'OT',
  icon: Gauge,
  moduleKey: 'operations_throughput'
};

export const orderingItem: NavItem = {
  href: '/ordering',
  label: 'Ordering',
  shortLabel: 'OR',
  icon: ShoppingCart,
  moduleKey: 'ordering'
};

/** Third-level submenu under Integrations. Each connected system is its own row. */
export const integrationsChildren: NavItem[] = [
  { href: '/ordering/manage/integrations/xero', label: 'Xero', shortLabel: 'XE', icon: Link2, moduleKey: 'ordering' }
];

/**
 * Children of the internal "Order Management" family. The first entry points at
 * the management root (`/ordering/manage`) which renders the order queue, so it
 * needs `exact` matching to avoid lighting up on its sibling routes. Integrations
 * is itself a parent: it links to the integrations landing and expands to its
 * connected systems (Xero) as a third sidebar layer.
 */
export const orderingManageChildren: NavItem[] = [
  { href: '/ordering/manage', label: 'Orders', shortLabel: 'OQ', icon: ListOrdered, moduleKey: 'ordering', exact: true },
  { href: '/ordering/manage/products', label: 'Products', shortLabel: 'PR', icon: Package, moduleKey: 'ordering' },
  { href: '/ordering/manage/customers', label: 'Customers', shortLabel: 'CU', icon: Users, moduleKey: 'ordering' },
  { href: '/ordering/manage/pricing', label: 'Pricing', shortLabel: 'PX', icon: Tags, moduleKey: 'ordering' },
  { href: '/ordering/manage/settings', label: 'Settings', shortLabel: 'ST', icon: SlidersHorizontal, moduleKey: 'ordering' },
  { href: '/ordering/manage/integrations', label: 'Integrations', shortLabel: 'IN', icon: Plug, moduleKey: 'ordering', exact: true, children: integrationsChildren }
];

/** The collapsible Order Management family for internal staff. */
export const orderingManageGroup: NavGroup = {
  id: 'ordering',
  label: 'Order Management',
  icon: ShoppingCart,
  href: '/ordering/manage',
  exact: true,
  children: orderingManageChildren
};

export const workingDocumentItems: NavItem[] = [
  // Mix Master remains available through the existing route and access logic,
  // but is temporarily hidden from the sidebar.
];

export const accessControlItem: NavItem = {
  href: '/client-access',
  label: 'Client Access',
  shortLabel: 'AC',
  icon: ShieldCheck,
  moduleKey: 'client_access'
};

export const clientNavigationItems: NavItem[] = [
  dashboardItem,
  mixCalculatorItem,
  productCostingItem,
  throughputItem,
  editorItem,
  ingredientsEditorItem,
  accessControlItem
];

export const footerLinks: FooterLink[] = [];

export const baseSearchItems: SearchItem[] = [
  {
    href: '/product-costing',
    label: 'Open Product Costing',
    description: 'Maintain product costing records, assumptions, and calculated pricing.',
    keywords: 'alpha product costing pricing finished delivered distributor wholesale margin spreadsheet'
  },
  {
    href: '/editor',
    label: 'Open Mix Editor',
    description: 'Edit mix names, status, and ingredients from one table.',
    keywords: 'editor mixes clients names status ingredients recipe table phf horse manning'
  },
  {
    href: '/ingredients',
    label: 'Open Ingredients Editor',
    description: 'Curate the raw material ingredients available to mixes.',
    keywords: 'ingredients editor raw materials supplier unit kg per unit catalogue mixes'
  },
  {
    href: '/',
    label: 'Open Dashboard',
    description: 'Jump to the Hunter Premium Produce workspace summary.',
    keywords: 'hunter premium produce overview dashboard workspace home'
  },
  {
    href: '/mixes',
    label: 'Open Mix Master',
    description: 'Browse saved mixes and their costing outputs.',
    keywords: 'mix master mixes recipes spreadsheet'
  },
  {
    href: '/mixes/new',
    label: 'Create New Mix',
    description: 'Start a new costing worksheet for Hunter Premium Produce.',
    keywords: 'new mix create worksheet hunter premium produce formula'
  },
  ...(featureFlags.mixCalculatorSessionHistory
    ? [
        {
          href: '/mix-calculator',
          label: 'Open Mix Calculator',
          description: 'Review saved production sessions and batch calculations.',
          keywords: 'mix calculator production sessions batch bags client product'
        }
      ]
    : []),
  {
    href: '/mix-calculator',
    label: 'Open Mix Calculator',
    description: 'Run a new client-specific mix calculation session.',
    keywords: 'new mix calculator session client batch size product bags print'
  },
  {
    href: '/reporting',
    label: 'Open Reporting',
    description: 'View raw material costs, mix summaries, product pricing, and data quality reports.',
    keywords: 'reporting reports raw materials mix cost product pricing data quality price review'
  },
  {
    href: '/settings',
    label: 'Open Workspace Settings',
    description: 'Review account details and workspace preferences.',
    keywords: 'settings account preferences profile workspace'
  },
];

/**
 * Assemble the grouped primary rail from already access-filtered items.
 * Callers pass only the modules the current session may see; empty families
 * collapse away so a role with one costing tool never gets an empty group.
 *
 * Workflow-family layout: Dashboard, then an "Operations" group (the mix
 * calculator and throughput) and a "Costing" group (product costing, mix and
 * ingredient editors, and master tools), then Ordering and Insights modules.
 */
export function buildClientNavEntries(visible: {
  dashboard?: NavItem | null;
  operations: NavItem[];
  costing: NavItem[];
  ordering?: NavEntry | null;
  reporting?: NavItem | null;
}): NavEntry[] {
  const entries: NavEntry[] = [];

  if (visible.dashboard) {
    entries.push({ kind: 'item', item: visible.dashboard });
  }

  if (visible.operations.length) {
    entries.push({
      kind: 'group',
      group: { id: 'operations', label: 'Operations', icon: Layers, children: visible.operations }
    });
  }

  if (visible.costing.length) {
    entries.push({
      kind: 'group',
      group: { id: 'costing', label: 'Costing', icon: BadgeDollarSign, children: visible.costing }
    });
  }

  if (visible.ordering) {
    entries.push(visible.ordering);
  }

  if (visible.reporting) {
    entries.push({ kind: 'item', item: visible.reporting });
  }

  return entries;
}

/** True when a row or any of its nested children matches the current route. */
function itemOrChildActive(item: NavItem, pathname: string): boolean {
  if (matchesRoute(item.href, pathname, item.exact)) return true;
  return item.children?.some((child) => matchesRoute(child.href, pathname, child.exact)) ?? false;
}

/** True when any of a group's children (or grandchildren) matches the route. */
export function groupHasActiveChild(group: NavGroup, pathname: string) {
  return group.children.some((child) => itemOrChildActive(child, pathname));
}

export function matchesRoute(href: string, pathname: string, exact = false) {
  if (href === '/') return pathname === '/';
  if (exact) return pathname === href;
  return pathname.startsWith(href);
}

/**
 * Resolve the deepest Order Management section row for a path, descending into
 * third-level submenus (Integrations → Xero) so headers and breadcrumbs name the
 * actual page rather than the parent. Returns null for the management root.
 */
export function findOrderingSection(pathname: string): NavItem | null {
  for (const child of orderingManageChildren) {
    // Check grandchildren first so a nested page (Xero) wins over its parent.
    for (const grandchild of child.children ?? []) {
      if (matchesRoute(grandchild.href, pathname, grandchild.exact)) return grandchild;
    }
    if (matchesRoute(child.href, pathname, child.exact)) return child;
  }
  return null;
}

export function pageTitle(pathname: string) {
  return pageMeta(pathname).title;
}

export function pageCategory(pathname: string) {
  return pageMeta(pathname).category;
}

export function pageMeta(pathname: string): PageMeta {
  if (pathname === '/') {
    return { title: 'Dashboard', category: 'Overview', icon: dashboardItem.icon };
  }

  if (pathname.startsWith('/ordering/manage')) {
    const section = findOrderingSection(pathname);
    return {
      title: section?.label ?? 'Orders',
      category: 'Order Management',
      icon: section?.icon ?? orderingManageGroup.icon
    };
  }

  if (pathname.startsWith('/ordering')) {
    return { title: 'Ordering', category: 'Ordering', icon: orderingItem.icon };
  }

  if (pathname.startsWith('/throughput/add')) {
    return { title: 'Add Entry', category: 'Operations', icon: throughputItem.icon };
  }

  if (pathname.startsWith('/throughput')) {
    return { title: throughputItem.label, category: 'Operations', icon: throughputItem.icon };
  }

  if (pathname.startsWith('/reporting')) {
    return { title: reportingItem.label, category: 'Insights', icon: reportingItem.icon };
  }

  if (pathname.startsWith('/mix-calculator')) {
    return { title: mixCalculatorItem.label, category: 'Operations', icon: mixCalculatorItem.icon };
  }

  if (pathname.startsWith('/product-costing')) {
    return { title: productCostingItem.label, category: 'Costing', icon: productCostingItem.icon };
  }

  if (pathname.startsWith('/editor')) {
    return { title: editorItem.label, category: 'Costing', icon: editorItem.icon };
  }

  if (pathname.startsWith('/ingredients')) {
    return { title: ingredientsEditorItem.label, category: 'Costing', icon: ingredientsEditorItem.icon };
  }

  if (pathname.startsWith('/raw-materials')) {
    return { title: 'Raw Materials', category: 'Operations', icon: FlaskConical };
  }

  if (pathname.startsWith('/products')) {
    return { title: 'Products', category: 'Operations', icon: Package };
  }

  if (pathname.startsWith('/mixes/new')) {
    return { title: 'New Mix', category: 'Operations', icon: ClipboardPenLine };
  }

  if (pathname.startsWith('/mixes')) {
    return { title: 'Mix Master', category: 'Operations', icon: Layers };
  }

  if (pathname.startsWith('/scenarios')) {
    return { title: 'Scenarios', category: 'Operations', icon: Layers };
  }

  if (pathname.startsWith('/client-access')) {
    return { title: accessControlItem.label, category: 'Administration', icon: accessControlItem.icon };
  }

  if (pathname.startsWith('/settings')) {
    return { title: 'Settings', category: 'Workspace', icon: Settings };
  }

  return { title: 'Workspace', category: 'Workspace', icon: LayoutDashboard };
}

export function clientBreadcrumbs(pathname: string, session?: AppSession | null): Crumb[] {
  const crumbs: Crumb[] = [];

  if (canOpenDashboard(session)) {
    crumbs.push({ label: 'Workspace', href: '/' });
  }

  if (pathname === '/') {
    return crumbs.length ? [...crumbs, { label: 'Dashboard' }] : [{ label: 'Dashboard' }];
  }

  if (pathname.startsWith('/mix-calculator')) {
    return [...crumbs, { label: 'Mix Calculator' }];
  }

  if (pathname.startsWith('/product-costing')) {
    return [...crumbs, { label: 'Product Costing' }];
  }

  if (pathname.startsWith('/editor')) {
    return [...crumbs, { label: 'Mix Editor' }];
  }

  if (pathname.startsWith('/mixes')) {
    return [...crumbs, { label: 'Mix Master' }];
  }

  if (pathname.startsWith('/throughput')) {
    const base: Crumb[] = [...crumbs, { label: 'Throughput', href: '/throughput' }];
    if (pathname === '/throughput/add') return [...base, { label: 'Add Entry' }];
    if (pathname === '/throughput') return base.slice(0, -1).concat([{ label: 'Throughput' }]);
    return base;
  }

  if (pathname.startsWith('/ordering/manage')) {
    const section = findOrderingSection(pathname);
    if (!section || section.href === '/ordering/manage') {
      return [...crumbs, { label: 'Order Management' }];
    }
    const chain: Crumb[] = [...crumbs, { label: 'Order Management', href: '/ordering/manage' }];
    // When the section is a nested grandchild (e.g. Xero), include its parent
    // (Integrations) as an intermediate crumb.
    const parent = orderingManageChildren.find((c) => c.children?.includes(section));
    if (parent) chain.push({ label: parent.label, href: parent.href });
    chain.push({ label: section.label });
    return chain;
  }

  const sectionMap: Record<string, string> = {
    '/raw-materials': 'Raw Materials',
    '/product-costing': 'Product Costing',
    '/products': 'Products',
    '/scenarios': 'Scenarios',
    '/client-access': 'Client Access',
    '/reporting': 'Reporting',
    '/settings': 'Settings',
    '/throughput': 'Throughput'
  };
  const section = sectionMap[pathname];
  if (section) return [...crumbs, { label: section }];

  return [...crumbs, { label: pageTitle(pathname) }];
}
