/**
 * MandateNavigation
 * 
 * Hierarchische Navigation für das Multi-Tenant-System.
 * Verwendet TreeNavigation für flexible Baumstruktur.
 * 
 * Navigation wird vollständig vom Backend geladen (/api/navigation).
 * Backend liefert Blocks-Struktur mit Static und Dynamic Blocks.
 * UI mappt uiComponent zu Icons via pageRegistry.
 * 
 * Struktur (gemäss Navigation-API-Konzept):
 * - SYSTEM (static block, order: 10)
 * - MEINE FEATURES (dynamic block, order: 15)
 *   - Mandant 1
 *     - Feature A
 *       - Instanz 1 (mit Views)
 * - WORKFLOWS (static block, order: 20)
 * - BASISDATEN (static block, order: 30)
 * - MIGRATE TO FEATURES (static block, order: 40)
 * - ADMINISTRATION (static block, order: 200)
 */

import React, { useMemo } from 'react';
import { useNavigation } from '../../hooks/useNavigation';
import type { 
  StaticBlock, 
  DynamicBlock, 
  NavigationItem,
  NavigationMandate,
  MandateFeature,
  FeatureInstance,
  FeatureView
} from '../../hooks/useNavigation';
import { getPageIcon } from '../../config/pageRegistry';
import { FaSpinner } from 'react-icons/fa';
import { TreeNavigation, type TreeItem, type TreeNodeItem } from './TreeNavigation';
import styles from './MandateNavigation.module.css';

// =============================================================================
// HELPER FUNCTIONS - Convert API blocks to TreeItems
// =============================================================================

/**
 * Convert a NavigationItem (from static block) to TreeNodeItem
 */
function navigationItemToTreeNode(item: NavigationItem): TreeNodeItem {
  return {
    id: item.objectKey,
    label: item.uiLabel,
    icon: getPageIcon(item.uiComponent),
    path: item.uiPath,
  };
}

/**
 * Convert a StaticBlock to TreeItem (section)
 */
function staticBlockToTreeItem(block: StaticBlock): TreeItem {
  return {
    type: 'section',
    title: block.title,
    children: block.items.map(navigationItemToTreeNode),
  };
}

/**
 * Convert a FeatureView to TreeNodeItem
 */
function featureViewToTreeNode(view: FeatureView): TreeNodeItem {
  return {
    id: view.objectKey,
    label: view.uiLabel,
    path: view.uiPath,
  };
}

/**
 * Convert a FeatureInstance to TreeNodeItem
 */
function featureInstanceToTreeNode(instance: FeatureInstance): TreeNodeItem {
  return {
    id: instance.id,
    label: instance.uiLabel,
    children: instance.views.map(featureViewToTreeNode),
    defaultExpanded: false,
  };
}

/**
 * Convert a MandateFeature to TreeNodeItem
 */
function mandateFeatureToTreeNode(feature: MandateFeature): TreeNodeItem | null {
  if (feature.instances.length === 0) {
    return null;
  }
  
  return {
    id: feature.uiComponent,
    label: feature.uiLabel,
    icon: getPageIcon(feature.uiComponent),
    badge: feature.instances.length,
    children: feature.instances.map(featureInstanceToTreeNode),
    defaultExpanded: false,
  };
}

/**
 * Convert a NavigationMandate to TreeNodeItem
 */
function navigationMandateToTreeNode(mandate: NavigationMandate): TreeNodeItem | null {
  if (mandate.features.length === 0) {
    return null;
  }
  
  const children = mandate.features
    .map(mandateFeatureToTreeNode)
    .filter((node): node is TreeNodeItem => node !== null);
  
  if (children.length === 0) {
    return null;
  }
  
  return {
    id: mandate.id,
    label: mandate.uiLabel,
    children,
    defaultExpanded: true,
  };
}

/**
 * Convert a DynamicBlock to array of TreeNodeItems (mandate nodes)
 */
function dynamicBlockToTreeNodes(block: DynamicBlock): TreeNodeItem[] {
  return block.mandates
    .map(navigationMandateToTreeNode)
    .filter((node): node is TreeNodeItem => node !== null);
}

// =============================================================================
// LOADING STATE
// =============================================================================

const LoadingState: React.FC = () => (
  <div className={styles.loadingState}>
    <FaSpinner className={styles.spinner} />
    <span>Navigation wird geladen...</span>
  </div>
);

// =============================================================================
// EMPTY STATE
// =============================================================================

const EmptyState: React.FC = () => (
  <div className={styles.emptyState}>
    <p>Keine Feature-Instanzen verfügbar.</p>
    <p className={styles.emptyHint}>
      Kontaktiere einen Administrator, um Zugriff zu erhalten.
    </p>
  </div>
);

// =============================================================================
// MAIN COMPONENT
// =============================================================================

export const MandateNavigation: React.FC = () => {
  // Fetch navigation from new API (blocks structure, already filtered by permissions)
  const { blocks, loading } = useNavigation('de');
  
  // Build navigation items from blocks
  const navigationItems: TreeItem[] = useMemo(() => {
    const items: TreeItem[] = [];
    
    // Process blocks in order (already sorted by backend)
    for (const block of blocks) {
      if (block.type === 'static') {
        // Static block: system, workflows, basedata, migrate, admin
        if (block.items.length > 0) {
          // Add separator before admin block
          if (block.id === 'admin') {
            items.push({ type: 'separator' });
          }
          items.push(staticBlockToTreeItem(block));
        }
      } else if (block.type === 'dynamic') {
        // Dynamic block: features/mandates
        // Add separator before dynamic block
        items.push({ type: 'separator' });
        
        const mandateNodes = dynamicBlockToTreeNodes(block);
        if (mandateNodes.length > 0) {
          items.push(...mandateNodes);
        }
        
        // Add separator after dynamic block (before next static blocks)
        items.push({ type: 'separator' });
      }
    }
    
    // Remove trailing separator if present
    while (items.length > 0 && (items[items.length - 1] as TreeItem & { type?: string }).type === 'separator') {
      items.pop();
    }
    
    return items;
  }, [blocks]);
  
  // Check if user has any navigation (static or dynamic)
  const hasNavigation = blocks.length > 0;
  
  // Show loading state while navigation is being fetched
  if (loading) {
    return (
      <div className={styles.navigation}>
        <LoadingState />
      </div>
    );
  }
  
  return (
    <div className={styles.navigation}>
      {hasNavigation ? (
        <TreeNavigation
          items={navigationItems}
          autoExpandActive={true}
        />
      ) : (
        <EmptyState />
      )}
    </div>
  );
};

export default MandateNavigation;
