/**
 * 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 { usePrompt } from '../../hooks/usePrompt';
import { useToast } from '../../contexts/ToastContext';
import api from '../../api';
import { useLanguage } from '../../providers/language/LanguageContext';
import styles from './MandateNavigation.module.css';

type NavTranslateFn = (key: string, params?: Record<string, string | number>) => string;

// =============================================================================
// 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) | undefined,
  tr: NavTranslateFn,
): TreeNodeItem {
  const children = instance.views.map(featureViewToTreeNode);
  const renameAction = instance.isAdmin && onRename ? (
    <button
      className={styles.renameButton}
      title={tr('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) | undefined,
  tr: NavTranslateFn,
): 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, tr));
    }
  }
  
  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) | undefined,
  tr: NavTranslateFn,
): TreeNodeItem[] {
  return block.mandates
    .map((m) => navigationMandateToTreeNode(m, onRename, tr))
    .filter((node): node is TreeNodeItem => node !== null);
}

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

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

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

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

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

export const MandateNavigation: React.FC = () => {
  const { t } = useLanguage();
  const { blocks, loading, refresh } = useNavigation('de');
  const { prompt, PromptDialog } = usePrompt();
  const { showWarning } = useToast();

  const _handleRename = useCallback(async (instanceId: string, currentLabel: string) => {
    const newLabel = await prompt(t('Neuer Name:'), { title: t('Umbenennen'), defaultValue: currentLabel });
    if (!newLabel || newLabel.trim() === currentLabel) return;
    try {
      await api.patch(`/api/features/instances/${instanceId}/rename`, { label: newLabel.trim() });
      refresh();
    } catch (err: any) {
      showWarning(t('Fehler'), t('Umbenennung fehlgeschlagen: {detail}', { detail: String(err?.response?.data?.detail || err.message) }));
    }
  }, [refresh, prompt, showWarning, t]);

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

    let systemBlock: { items: NavigationItem[]; subgroups?: NavSubgroup[] } | null = null;
    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.id === 'system') {
          systemBlock = { items: block.items || [], subgroups: block.subgroups };
        } else if (block.items.length > 0) {
          // Legacy: other static blocks get merged as flat items
          if (!systemBlock) systemBlock = { items: [], subgroups: [] };
          systemBlock.items.push(...block.items);
        }
      }
    }

    if (systemBlock) {
      const children: TreeNodeItem[] = [];
      for (const item of systemBlock.items) {
        children.push(navigationItemToTreeNode(item));
      }
      if (systemBlock.subgroups && systemBlock.subgroups.length > 0) {
        for (const sg of systemBlock.subgroups) {
          children.push({
            id: sg.id,
            label: sg.title,
            children: sg.items.map(navigationItemToTreeNode),
            defaultExpanded: true,
          });
        }
      }
      if (children.length > 0) {
        items.push({
          id: 'meine-sicht',
          label: t('Meine Sicht'),
          children,
          defaultExpanded: true,
        });
      }
    }

    for (const block of blocks) {
      if (block.type === 'dynamic') {
        const mandateNodes = dynamicBlockToTreeNodes(block, _handleRename, t);
        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: t('Administration'),
        children: subgroupNodes,
        defaultExpanded: false,
      });
    } else if (adminItems.length > 0) {
      if (items.length > 0) items.push({ type: 'separator' });
      items.push(_staticItemsToTreeNode('administration', t('Administration'), adminItems, false));
    }

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

export default MandateNavigation;
