/**
 * 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.
 * 
 * TREE STRUCTURE (alles collapsible):
 * ▼ Meine Sicht
 *   - Übersicht, Einstellungen, Prompts, Dateien, Verbindungen, Billing
 * ─────────────
 * ▼ Mandant 1
 *   - 🎯 Instanz 1 (Feature-Icon + Instanz-Name)
 *   - 💼 Instanz 2 (Feature-Icon + Instanz-Name)
 * ─────────────
 * ▶ Administration
 *   - Users, Mandates, Roles, ...
 */

import React, { useMemo, useCallback } from 'react';
import { useNavigation } from '../../hooks/useNavigation';
import type { 
  DynamicBlock, 
  NavigationItem,
  NavSubgroup,
  NavigationMandate,
  FeatureInstance,
  FeatureView
} from '../../hooks/useNavigation';
import { getPageIcon } from '../../config/pageRegistry';
import { FaSpinner, FaPen } from 'react-icons/fa';
import { TreeNavigation, type TreeItem, type TreeNodeItem } from './TreeNavigation';
import api from '../../api';
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 list of NavigationItems into a collapsible TreeNodeItem container.
 * Used for grouping static items under "Meine Sicht" and "Administration".
 */
function _staticItemsToTreeNode(
  id: string,
  label: string,
  items: NavigationItem[],
  defaultExpanded: boolean = true,
): TreeNodeItem {
  return {
    id,
    label,
    children: items.map(navigationItemToTreeNode),
    defaultExpanded,
  };
}

/**
 * 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 (with feature icon)
 * Instance node gets path to first view so clicking the instance name navigates to dashboard.
 * Shows the feature icon next to the instance name for visual distinction.
 * If user is instance admin, a rename icon appears on hover.
 */
function featureInstanceToTreeNode(
  instance: FeatureInstance,
  featureUiComponent: string,
  onRename?: (instanceId: string, currentLabel: string) => void,
): TreeNodeItem {
  const children = instance.views.map(featureViewToTreeNode);
  const renameAction = instance.isAdmin && onRename ? (
    <button
      className={styles.renameButton}
      title="Umbenennen"
      onClick={(e) => { e.preventDefault(); e.stopPropagation(); onRename(instance.id, instance.uiLabel); }}
    >
      <FaPen size={10} />
    </button>
  ) : undefined;

  return {
    id: instance.id,
    label: instance.uiLabel,
    icon: getPageIcon(featureUiComponent),
    path: instance.views.length > 0 ? instance.views[0].uiPath : undefined,
    children,
    defaultExpanded: false,
    actions: renameAction,
  };
}

/**
 * Convert a NavigationMandate to TreeNodeItem
 * 
 * FLAT STRUCTURE: Instances are listed directly under mandate (no feature grouping).
 * Each instance shows the feature's icon for visual distinction.
 * 
 * Before: Mandate → Feature → Instance → Views
 * Now:    Mandate → Instance (with feature icon) → Views
 */
function navigationMandateToTreeNode(
  mandate: NavigationMandate,
  onRename?: (instanceId: string, currentLabel: string) => void,
): TreeNodeItem | null {
  if (mandate.features.length === 0) {
    return null;
  }
  
  const instanceNodes: TreeNodeItem[] = [];
  for (const feature of mandate.features) {
    for (const instance of feature.instances) {
      instanceNodes.push(featureInstanceToTreeNode(instance, feature.uiComponent, onRename));
    }
  }
  
  if (instanceNodes.length === 0) {
    return null;
  }
  
  return {
    id: mandate.id,
    label: mandate.uiLabel,
    children: instanceNodes,
    defaultExpanded: true,
  };
}

/**
 * Convert a DynamicBlock to array of TreeNodeItems (mandate nodes)
 */
function dynamicBlockToTreeNodes(
  block: DynamicBlock,
  onRename?: (instanceId: string, currentLabel: string) => void,
): TreeNodeItem[] {
  return block.mandates
    .map((m) => navigationMandateToTreeNode(m, onRename))
    .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 = () => {
  const { blocks, loading, refresh } = useNavigation('de');

  const _handleRename = useCallback((instanceId: string, currentLabel: string) => {
    const newLabel = window.prompt('Neuer Name:', currentLabel);
    if (!newLabel || newLabel.trim() === currentLabel) return;
    api.patch(`/api/features/instances/${instanceId}/rename`, { label: newLabel.trim() })
      .then(() => refresh())
      .catch((err: any) => alert('Umbenennung fehlgeschlagen: ' + (err?.response?.data?.detail || err.message)));
  }, [refresh]);

  const navigationItems: TreeItem[] = useMemo(() => {
    const items: TreeItem[] = [];

    const meineSichtItems: NavigationItem[] = [];
    let adminItems: NavigationItem[] = [];
    let adminSubgroups: NavSubgroup[] = [];

    for (const block of blocks) {
      if (block.type === 'static') {
        if (block.id === 'admin') {
          if (block.subgroups && block.subgroups.length > 0) {
            adminSubgroups = block.subgroups;
          } else {
            adminItems = [...block.items];
          }
        } else if (block.items.length > 0) {
          meineSichtItems.push(...block.items);
        }
      }
    }

    if (meineSichtItems.length > 0) {
      items.push(_staticItemsToTreeNode('meine-sicht', 'Meine Sicht', meineSichtItems, true));
    }

    for (const block of blocks) {
      if (block.type === 'dynamic') {
        const mandateNodes = dynamicBlockToTreeNodes(block, _handleRename);
        if (mandateNodes.length > 0) {
          if (items.length > 0) items.push({ type: 'separator' });
          items.push(...mandateNodes);
        }
      }
    }

    if (adminSubgroups.length > 0) {
      if (items.length > 0) items.push({ type: 'separator' });
      const subgroupNodes: TreeNodeItem[] = adminSubgroups.map(sg => ({
        id: sg.id,
        label: sg.title,
        children: sg.items.map(navigationItemToTreeNode),
        defaultExpanded: false,
      }));
      items.push({
        id: 'administration',
        label: 'Administration',
        children: subgroupNodes,
        defaultExpanded: false,
      });
    } else if (adminItems.length > 0) {
      if (items.length > 0) items.push({ type: 'separator' });
      items.push(_staticItemsToTreeNode('administration', 'Administration', adminItems, false));
    }

    return items;
  }, [blocks, _handleRename]);
  
  // 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;
