import { createElement, type ReactNode } from 'react';
import type { SidebarTreeNode } from '@cameleer/design-system';
import { AlertTriangle, Inbox, BellOff } from 'lucide-react';

/* ------------------------------------------------------------------ */
/*  Domain types (moved out of DS — no longer exported there)         */
/* ------------------------------------------------------------------ */

export interface SidebarRoute {
  id: string;
  name: string;
  exchangeCount: number;
  routeState?: 'stopped' | 'suspended';
}

export interface SidebarApp {
  id: string;
  name: string;
  health: 'live' | 'stale' | 'dead' | 'running' | 'error';
  healthTooltip?: string;
  exchangeCount: number;
  routes: SidebarRoute[];
}

/* ------------------------------------------------------------------ */
/*  Formatting helpers                                                */
/* ------------------------------------------------------------------ */

export function formatCount(n: number): string {
  if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}m`;
  if (n >= 1_000) return `${(n / 1_000).toFixed(1)}k`;
  return String(n);
}

/* ------------------------------------------------------------------ */
/*  localStorage collapse helpers                                     */
/* ------------------------------------------------------------------ */

export function readCollapsed(key: string, defaultValue: boolean): boolean {
  try {
    const raw = localStorage.getItem(key);
    if (raw === null) return defaultValue;
    return raw === 'true';
  } catch {
    return defaultValue;
  }
}

export function writeCollapsed(key: string, value: boolean): void {
  try {
    localStorage.setItem(key, String(value));
  } catch {
    // ignore quota errors
  }
}

/* ------------------------------------------------------------------ */
/*  Tree builders                                                     */
/* ------------------------------------------------------------------ */

/**
 * Apps tree — one node per app, routes as children.
 * Paths: /exchanges/{appId}, /exchanges/{appId}/{routeId}
 */
export function buildAppTreeNodes(
  apps: SidebarApp[],
  statusDot: (health: string) => ReactNode,
  chevron: () => ReactNode,
  stopIcon?: () => ReactNode,
  pauseIcon?: () => ReactNode,
): SidebarTreeNode[] {
  return apps.map((app) => ({
    id: app.id,
    label: app.name,
    icon: app.healthTooltip
      ? createElement('span', { title: app.healthTooltip }, statusDot(app.health))
      : statusDot(app.health),
    badge: formatCount(app.exchangeCount),
    path: `/exchanges/${app.id}`,
    starrable: true,
    starKey: `app:${app.id}`,
    children: app.routes.map((r) => ({
      id: `${app.id}/${r.id}`,
      label: r.name,
      icon: r.routeState === 'stopped' && stopIcon
        ? stopIcon()
        : r.routeState === 'suspended' && pauseIcon
          ? pauseIcon()
          : chevron(),
      badge: r.routeState
        ? `${r.routeState.toUpperCase()} \u00b7 ${formatCount(r.exchangeCount)}`
        : formatCount(r.exchangeCount),
      path: `/exchanges/${app.id}/${r.id}`,
      starrable: true,
      starKey: `route:${app.id}/${r.id}`,
    })),
  }));
}

/**
 * Admin tree — static nodes, alphabetically sorted.
 */
export function buildAdminTreeNodes(opts?: { infrastructureEndpoints?: boolean }): SidebarTreeNode[] {
  const showInfra = opts?.infrastructureEndpoints !== false;
  const nodes: SidebarTreeNode[] = [
    { id: 'admin:audit', label: 'Audit Log', path: '/admin/audit' },
    ...(showInfra ? [{ id: 'admin:clickhouse', label: 'ClickHouse', path: '/admin/clickhouse' }] : []),
    ...(showInfra ? [{ id: 'admin:database', label: 'Database', path: '/admin/database' }] : []),
    { id: 'admin:environments', label: 'Environments', path: '/admin/environments' },
    { id: 'admin:oidc', label: 'OIDC', path: '/admin/oidc' },
    { id: 'admin:outbound-connections', label: 'Outbound Connections', path: '/admin/outbound-connections' },
    { id: 'admin:sensitive-keys', label: 'Sensitive Keys', path: '/admin/sensitive-keys' },
    ...(showInfra ? [{ id: 'admin:server-metrics', label: 'Server Metrics', path: '/admin/server-metrics' }] : []),
    { id: 'admin:rbac', label: 'Users & Roles', path: '/admin/rbac' },
  ];
  return nodes;
}

/**
 * Alerts tree — static nodes for the alerting section.
 * Paths: /alerts/{inbox|rules|silences}
 */
export function buildAlertsTreeNodes(): SidebarTreeNode[] {
  const icon = (el: ReactNode) => el;
  return [
    { id: 'alerts-inbox',    label: 'Inbox',    path: '/alerts/inbox',    icon: icon(createElement(Inbox, { size: 14 })) },
    { id: 'alerts-rules',    label: 'Rules',    path: '/alerts/rules',    icon: icon(createElement(AlertTriangle, { size: 14 })) },
    { id: 'alerts-silences', label: 'Silences', path: '/alerts/silences', icon: icon(createElement(BellOff, { size: 14 })) },
  ];
}
