import { useState, useCallback, useEffect } from 'react';
import api from '../api';
import type { GenericDataHook } from '../core/PageManager/pageInterface';
import { fetchAttributes } from '../api/attributesApi';
import { useApiRequest } from './useApi';
import { usePermissions, type UserPermissions } from './usePermissions';
import { 
  isDateTimeType, 
  isSelectType, 
  isMultiselectType, 
  isCheckboxType, 
  isTextareaType,
  type AttributeType 
} from '../utils/attributeTypeMapper';

// Table list response interface
export interface TableInfo {
  name: string;
  description: string;
  model: string;
}

export interface TablesListResponse {
  tables: TableInfo[];
  count: number;
}

// Command response interface
export interface CommandResponse {
  success: boolean;
  intent: string;
  entity: string;
  result: any;
  message?: string;
}

// Table data response interface
export interface TableDataResponse {
  items: any[];
  pagination: {
    currentPage: number;
    pageSize: number;
    totalItems: number;
    totalPages: number;
    sort?: Array<{ field: string; direction: 'asc' | 'desc' }>;
    filters?: any;
  } | null;
}

// Message interface for chat
export interface PekMessage {
  id: string;
  role: 'user' | 'assistant';
  message: string;
  timestamp: Date;
  data?: any;
}

export function usePekTables() {
  // Tables list state - initialize as empty array
  const [tables, setTables] = useState<TableInfo[]>([]);
  const [isLoadingTables, setIsLoadingTables] = useState(false);
  const [tablesError, setTablesError] = useState<string | null>(null);

  // Selected table state
  const [selectedTable, setSelectedTable] = useState<string>('');
  const [tableData, setTableData] = useState<any[]>([]);
  const [isLoadingTableData, setIsLoadingTableData] = useState(false);
  const [tableDataError, setTableDataError] = useState<string | null>(null);
  const [pagination, setPagination] = useState<TableDataResponse['pagination']>(null);

  // Command state
  const [commandInput, setCommandInput] = useState<string>('');
  const [isProcessingCommand, setIsProcessingCommand] = useState(false);
  const [commandError, setCommandError] = useState<string | null>(null);
  const [messages, setMessages] = useState<PekMessage[]>([]);

  /**
   * Load list of available tables
   */
  const loadTables = useCallback(async () => {
    setIsLoadingTables(true);
    setTablesError(null);

    try {
      const response = await api.get('/api/realestate/tables');
      const data: TablesListResponse = response.data;
      setTables(data.tables || []);

      // Auto-select first table if available
      if (data.tables && data.tables.length > 0 && !selectedTable) {
        setSelectedTable(data.tables[0].model);
      }
    } catch (err: any) {
      const errorMessage =
        err.response?.data?.detail || err.message || 'Fehler beim Laden der Tabellen';
      setTablesError(errorMessage);
    } finally {
      setIsLoadingTables(false);
    }
  }, [selectedTable]);

  /**
   * Load data for a specific table
   */
  const loadTableData = useCallback(async (tableName: string, page?: number, pageSize?: number, sort?: Array<{ field: string; direction: 'asc' | 'desc' }>) => {
    setIsLoadingTableData(true);
    setTableDataError(null);

    try {
      const params: any = {};
      
      // Build pagination object if provided
      if (page !== undefined || pageSize !== undefined || sort) {
        params.pagination = JSON.stringify({
          page: page || 1,
          pageSize: pageSize || 10,
          sort: sort || []
        });
      }

      const response = await api.get(`/api/realestate/table/${tableName}`, { params });
      const data: TableDataResponse = response.data;
      
      setTableData(data.items || []);
      setPagination(data.pagination);
    } catch (err: any) {
      const errorMessage =
        err.response?.data?.detail || err.message || `Fehler beim Laden der Tabelle ${tableName}`;
      setTableDataError(errorMessage);
    } finally {
      setIsLoadingTableData(false);
    }
  }, []);

  // Load tables list on mount
  useEffect(() => {
    loadTables();
  }, [loadTables]);

  // Load table data when selected table changes
  useEffect(() => {
    if (selectedTable) {
      loadTableData(selectedTable);
    } else {
      setTableData([]);
      setPagination(null);
    }
  }, [selectedTable, loadTableData]);

  /**
   * Process natural language command
   */
  const processCommand = useCallback(async (userInput: string) => {
    if (!userInput.trim()) {
      setCommandError('Bitte geben Sie einen Befehl ein.');
      return;
    }

    setIsProcessingCommand(true);
    setCommandError(null);

    // Add user message
    const userMessage: PekMessage = {
      id: `user-${Date.now()}`,
      role: 'user',
      message: userInput,
      timestamp: new Date()
    };
    setMessages((prev) => [...prev, userMessage]);

    try {
      const response = await api.post('/api/realestate/command', {
        userInput: userInput.trim()
      });

      const data: CommandResponse = response.data;

      // Add assistant message
      const assistantMessage: PekMessage = {
        id: `assistant-${Date.now()}`,
        role: 'assistant',
        message: data.message || `Befehl erfolgreich ausgeführt: ${data.intent} ${data.entity}`,
        timestamp: new Date(),
        data: data.result
      };
      setMessages((prev) => [...prev, assistantMessage]);

      // Reload table data if command might have affected it
      if (selectedTable && (data.intent === 'CREATE' || data.intent === 'UPDATE' || data.intent === 'DELETE')) {
        await loadTableData(selectedTable);
      }

      // Clear input
      setCommandInput('');

      return { success: true, data };
    } catch (err: any) {
      const errorMessage =
        err.response?.data?.detail || err.message || 'Fehler beim Verarbeiten des Befehls';
      setCommandError(errorMessage);

      // Add error message
      const errorMsg: PekMessage = {
        id: `error-${Date.now()}`,
        role: 'assistant',
        message: `Fehler: ${errorMessage}`,
        timestamp: new Date()
      };
      setMessages((prev) => [...prev, errorMsg]);

      return { success: false, error: errorMessage };
    } finally {
      setIsProcessingCommand(false);
    }
  }, [selectedTable, loadTableData]);

  /**
   * Create a new record in the selected table
   */
  const createRecord = useCallback(async (tableName: string, data: any) => {
    try {
      const response = await api.post(`/api/realestate/table/${tableName}`, data);
      
      // Reload table data
      if (tableName === selectedTable) {
        await loadTableData(selectedTable);
      }

      return { success: true, data: response.data };
    } catch (err: any) {
      const errorMessage =
        err.response?.data?.detail || err.message || 'Fehler beim Erstellen des Eintrags';
      return { success: false, error: errorMessage };
    }
  }, [selectedTable, loadTableData]);

  /**
   * Refresh current table data
   */
  const refreshTableData = useCallback(() => {
    if (selectedTable) {
      loadTableData(selectedTable);
    }
  }, [selectedTable, loadTableData]);

  return {
    // Tables list
    tables,
    isLoadingTables,
    tablesError,
    loadTables,

    // Selected table
    selectedTable,
    setSelectedTable,
    tableData,
    isLoadingTableData,
    tableDataError,
    pagination,
    loadTableData,
    refreshTableData,

    // Commands
    commandInput,
    setCommandInput,
    processCommand,
    isProcessingCommand,
    commandError,
    messages,

    // Create record
    createRecord
  };
}

/**
 * Hook factory that creates a hook for a specific table model
 * Returns a hook function compatible with GenericDataHook interface
 */
export function createPekTableHook(tableModel: string): () => GenericDataHook {
  return () => {
    const [tableData, setTableData] = useState<any[]>([]);
    const [isLoadingTableData, setIsLoadingTableData] = useState(false);
    const [tableDataError, setTableDataError] = useState<string | null>(null);
    const [pagination, setPagination] = useState<TableDataResponse['pagination']>(null);

    /**
     * Load data for the specific table
     */
    const loadTableData = useCallback(async (
      page?: number, 
      pageSize?: number, 
      sort?: Array<{ field: string; direction: 'asc' | 'desc' }>,
      filters?: any,
      search?: string
    ) => {
      setIsLoadingTableData(true);
      setTableDataError(null);

      try {
        const params: any = {};
        
        // Build pagination object
        const paginationObj: any = {
          page: page || 1,
          pageSize: pageSize || 10,
          sort: sort || []
        };

        if (filters) {
          paginationObj.filters = filters;
        }

        if (search) {
          paginationObj.search = search;
        }

        params.pagination = JSON.stringify(paginationObj);

        const response = await api.get(`/api/realestate/table/${tableModel}`, { params });
        const data: TableDataResponse = response.data;
        
        setTableData(data.items || []);
        setPagination(data.pagination);
      } catch (err: any) {
        const errorMessage =
          err.response?.data?.detail || err.message || `Fehler beim Laden der Tabelle ${tableModel}`;
        setTableDataError(errorMessage);
      } finally {
        setIsLoadingTableData(false);
      }
    }, [tableModel]);

    // Load table data on mount
    useEffect(() => {
      loadTableData();
    }, [loadTableData]);

    /**
     * Refetch function compatible with GenericDataHook interface
     */
    const refetch = useCallback(async (params?: {
      page?: number;
      pageSize?: number;
      sort?: Array<{field: string; direction: 'asc' | 'desc'}>;
      filters?: any;
      search?: string;
    }) => {
      await loadTableData(
        params?.page,
        params?.pageSize,
        params?.sort,
        params?.filters,
        params?.search
      );
    }, [loadTableData]);

    return {
      data: tableData,
      loading: isLoadingTableData,
      error: tableDataError,
      refetch,
      pagination: pagination || null,
      columns: undefined // Columns can be loaded from attributes API if needed
    };
  };
}

// Attribute definition interface
interface AttributeDefinition {
  name: string;
  label: string;
  type: AttributeType;
  sortable?: boolean;
  filterable?: boolean;
  searchable?: boolean;
  width?: number;
  minWidth?: number;
  maxWidth?: number;
  filterOptions?: string[];
  editable?: boolean;
  visible?: boolean;
}

// Helper function to convert attribute definitions to column config
const attributesToColumns = (attributes: AttributeDefinition[], hiddenColumns: string[] = []) => {
  return attributes
    .filter(attr => !hiddenColumns.includes(attr.name) && !hiddenColumns.includes(attr.label))
    .map(attr => {
      // Use attributeTypeMapper to check if this is a date/timestamp field - disable filtering for these
      const isDateField = isDateTimeType(attr.type);
      
      return {
        key: attr.name,
        label: attr.label || attr.name,
        type: attr.type || 'string',
        width: attr.width || 200,
        minWidth: attr.minWidth || 100,
        maxWidth: attr.maxWidth || 400,
        sortable: attr.sortable !== false,
        // Disable filtering for date/timestamp fields
        filterable: isDateField ? false : (attr.filterable !== false),
        searchable: attr.searchable !== false,
        filterOptions: attr.filterOptions
      };
    });
};

/**
 * Hook factory for Projekte table with edit/delete support
 */
export function createProjectsTableHook(): () => GenericDataHook {
  return () => {
    const [tableData, setTableData] = useState<any[]>([]);
    const [isLoadingTableData, setIsLoadingTableData] = useState(false);
    const [tableDataError, setTableDataError] = useState<string | null>(null);
    const [pagination, setPagination] = useState<TableDataResponse['pagination']>(null);
    const [attributes, setAttributes] = useState<AttributeDefinition[]>([]);
    const [permissions, setPermissions] = useState<UserPermissions | null>(null);
    const [editingProjects, setEditingProjects] = useState<Set<string>>(new Set());
    const [deletingProjects, setDeletingProjects] = useState<Set<string>>(new Set());
    const { request } = useApiRequest();
    const { checkPermission } = usePermissions();

    // Columns to hide in Projekte table
    const hiddenColumns = ['mandateId', 'Mandat Id', 'perimeter', 'Perimeter', 'dokumente', 'Dokumente', 'kontextInformationen', 'Kontext Informationen'];

    // Fetch attributes from backend
    const fetchAttributesData = useCallback(async () => {
      try {
        const attrs = await fetchAttributes(request, 'Projekt');
        setAttributes(attrs);
        return attrs;
      } catch (error: any) {
        console.error('Error fetching Projekt attributes:', error);
        setAttributes([]);
        return [];
      }
    }, [request]);

    // Fetch permissions from backend
    const fetchPermissionsData = useCallback(async () => {
      try {
        const perms = await checkPermission('DATA', 'Projekt');
        setPermissions(perms);
        return perms;
      } catch (error: any) {
        console.error('Error fetching permissions:', error);
        const defaultPerms: UserPermissions = {
          view: false,
          read: 'n',
          create: 'n',
          update: 'n',
          delete: 'n',
        };
        setPermissions(defaultPerms);
        return defaultPerms;
      }
    }, [checkPermission]);

    // Generate columns from attributes
    const generatedColumns = attributes && attributes.length > 0 
      ? attributesToColumns(attributes, hiddenColumns)
      : undefined;

    /**
     * Load data for the specific table
     */
    const loadTableData = useCallback(async (
      page?: number, 
      pageSize?: number, 
      sort?: Array<{ field: string; direction: 'asc' | 'desc' }>,
      filters?: any,
      search?: string
    ) => {
      setIsLoadingTableData(true);
      setTableDataError(null);

      try {
        const params: any = {};
        
        // Build pagination object
        const paginationObj: any = {
          page: page || 1,
          pageSize: pageSize || 10,
          sort: sort || []
        };

        if (filters) {
          paginationObj.filters = filters;
        }

        if (search) {
          paginationObj.search = search;
        }

        params.pagination = JSON.stringify(paginationObj);

        const response = await api.get(`/api/realestate/table/Projekt`, { params });
        const data: TableDataResponse = response.data;
        
        setTableData(data.items || []);
        setPagination(data.pagination);
      } catch (err: any) {
        const errorMessage =
          err.response?.data?.detail || err.message || `Fehler beim Laden der Tabelle Projekt`;
        setTableDataError(errorMessage);
      } finally {
        setIsLoadingTableData(false);
      }
    }, []);

    // Fetch a single project by ID
    const fetchProjectById = useCallback(async (id: string): Promise<any | null> => {
      try {
        // Load all projects and find the one with matching ID
        // Note: If backend supports GET /api/realestate/table/Projekt/{id}, use that instead
        const response = await api.get(`/api/realestate/table/Projekt`);
        const data: TableDataResponse = response.data;
        const project = (data.items || []).find((item: any) => item.id === id || item.id?.toString() === id);
        return project || null;
      } catch (err: any) {
        console.error('Error fetching project by ID:', err);
        return null;
      }
    }, []);

    // Update project
    const handleProjectUpdate = useCallback(async (id: string, updateData: any): Promise<{ success: boolean }> => {
      try {
        setEditingProjects(prev => new Set(prev).add(id));
        
        // Use command API for update
        const response = await api.post('/api/realestate/command', {
          userInput: `UPDATE Projekt ${id} with ${JSON.stringify(updateData)}`
        });

        const data: CommandResponse = response.data;
        
        if (data.success) {
          // Refetch table data
          await loadTableData();
          return { success: true };
        } else {
          return { success: false };
        }
      } catch (err: any) {
        console.error('Error updating project:', err);
        return { success: false };
      } finally {
        setEditingProjects(prev => {
          const next = new Set(prev);
          next.delete(id);
          return next;
        });
      }
    }, [loadTableData]);

    // Delete project
    const handleProjectDelete = useCallback(async (id: string): Promise<boolean> => {
      try {
        setDeletingProjects(prev => new Set(prev).add(id));
        
        // Use command API for delete
        const response = await api.post('/api/realestate/command', {
          userInput: `DELETE Projekt ${id}`
        });

        const data: CommandResponse = response.data;
        
        if (data.success) {
          // Refetch table data
          await loadTableData();
          return true;
        } else {
          return false;
        }
      } catch (err: any) {
        console.error('Error deleting project:', err);
        return false;
      } finally {
        setDeletingProjects(prev => {
          const next = new Set(prev);
          next.delete(id);
          return next;
        });
      }
    }, [loadTableData]);

    // Create project
    const handleProjectCreate = useCallback(async (projectData: any): Promise<{ success: boolean; data?: any; error?: string }> => {
      try {
        // The projectData now contains:
        // - label: string
        // - parzellen: Array<{ ...all parcel data including userAddress, geometry, map_view, adjacent_parcels, etc. }>
        // - mandateId is NOT included (set by backend)
        
        // Backward compatibility: if parzelle (singular) exists, convert to parzellen array
        if (projectData.parzelle && !projectData.parzellen) {
          projectData.parzellen = [projectData.parzelle];
          delete projectData.parzelle;
        }
        
        // Clean and flatten parzellen data: Extract parcel data from ParcelSearchResponse structure
        // Each parcel should use its own address data from Swiss Topo API
        if (projectData.parzellen && Array.isArray(projectData.parzellen)) {
          projectData.parzellen = projectData.parzellen.map((parzelleItem: any) => {
            // Handle both structures:
            // 1. ParcelSearchResponse structure: { parcel: {...}, map_view: {...}, adjacent_parcels: [...] }
            // 2. Already flattened structure: { id, address, plz, ... }
            let parcelData: any;
            
            if (parzelleItem.parcel) {
              // ParcelSearchResponse structure - extract parcel data and merge with map_view/adjacent_parcels
              parcelData = {
                ...parzelleItem.parcel,  // All parcel fields (id, address, plz, perimeter, etc.)
                // Preserve map_view and adjacent_parcels if needed
                map_view: parzelleItem.map_view,
                adjacent_parcels: parzelleItem.adjacent_parcels
              };
            } else {
              // Already flattened - use as-is
              parcelData = { ...parzelleItem };
            }
            
            // Remove userAddress to ensure Swiss Topo API data is used
            delete parcelData.userAddress;
            
            // Ensure address and plz from Swiss Topo are preserved
            // These come from the parcel search API response for THIS specific parcel
            return parcelData;
          });
        }
        
        // Send the complete project data structure to the backend
        const response = await api.post('/api/realestate/table/Projekt', projectData);

        // Refetch table data after successful creation
        await loadTableData();
        return { success: true, data: response.data };
      } catch (err: any) {
        console.error('Error creating project:', err);
        const errorMessage = err.response?.data?.detail || err.message || 'Fehler beim Erstellen des Projekts';
        return { success: false, error: errorMessage };
      }
    }, [loadTableData]);

    // Handle single project deletion for FormGenerator
    const handleDeleteSingle = useCallback(async (project: any) => {
      const success = await handleProjectDelete(project.id);
      
      if (success) {
        await loadTableData();
      }
    }, [handleProjectDelete, loadTableData]);

    // Handle multiple project deletion for FormGenerator
    const handleDeleteMultiple = useCallback(async (selectedProjects: any[]) => {
      const projectIds = selectedProjects.map(project => project.id);
      
      // Delete all projects sequentially
      const results = await Promise.all(
        projectIds.map(id => handleProjectDelete(id))
      );
      
      const allSuccessful = results.every(result => result);
      
      if (allSuccessful) {
        await loadTableData();
      }
    }, [handleProjectDelete, loadTableData]);

    // Optimistic update
    const updateOptimistically = useCallback((id: string, updateData: any) => {
      setTableData(prev => prev.map(item => {
        if (item.id === id || item.id?.toString() === id) {
          return { ...item, ...updateData };
        }
        return item;
      }));
    }, []);

    // Optimistic remove
    const removeOptimistically = useCallback((id: string) => {
      setTableData(prev => prev.filter(item => item.id !== id && item.id?.toString() !== id));
    }, []);

    // Generate edit fields from attributes for create button
    const generateEditFieldsFromAttributes = useCallback((): Array<{
      key: string;
      label: string;
      type: 'string' | 'boolean' | 'email' | 'textarea' | 'date' | 'enum' | 'multiselect' | 'readonly';
      editable?: boolean;
      required?: boolean;
      validator?: (value: any) => string | null;
      minRows?: number;
      maxRows?: number;
      options?: Array<{ value: string | number; label: string }>;
      optionsReference?: string;
    }> => {
      if (!attributes || attributes.length === 0) {
        return [];
      }

      const editableFields = attributes
        .filter(attr => {
          // Show all fields from backend - filter out ID fields and mandateId for create forms
          // mandateId is set by backend, not editable by user
          const nonEditableFields = ['id', 'mandateId']; // Filter out ID fields and mandateId for create forms
          return !nonEditableFields.includes(attr.name);
        })
        .map(attr => {
          // Map backend attribute type to form field type using attributeTypeMapper utilities
          let fieldType: 'string' | 'boolean' | 'email' | 'textarea' | 'date' | 'enum' | 'multiselect' | 'readonly' = 'string';
          let options: Array<{ value: string | number; label: string }> | undefined = undefined;
          let optionsReference: string | undefined = undefined;
          
          const attrType = attr.type as AttributeType;
          
          // Use attributeTypeMapper utilities to determine field type
          if (isCheckboxType(attrType)) {
            fieldType = 'boolean';
          } else if (attrType === 'email') {
            fieldType = 'email';
          } else if (isDateTimeType(attrType)) {
            fieldType = 'date';
          } else if (isSelectType(attrType)) {
            fieldType = 'enum';
            const attrOptions = (attr as any).options;
            if (Array.isArray(attrOptions)) {
              options = attrOptions.map((opt: any) => {
                const labelValue = typeof opt.label === 'string' 
                  ? opt.label 
                  : opt.label?.en || opt.label?.[Object.keys(opt.label || {})[0]] || String(opt.value);
                return {
                  value: opt.value,
                  label: labelValue
                };
              });
            } else if (typeof attrOptions === 'string') {
              optionsReference = attrOptions;
            }
          } else if (isMultiselectType(attrType)) {
            fieldType = 'multiselect';
            const attrOptions = (attr as any).options;
            if (Array.isArray(attrOptions)) {
              options = attrOptions.map((opt: any) => {
                const labelValue = typeof opt.label === 'string' 
                  ? opt.label 
                  : opt.label?.en || opt.label?.[Object.keys(opt.label || {})[0]] || String(opt.value);
                return {
                  value: opt.value,
                  label: labelValue
                };
              });
            } else if (typeof attrOptions === 'string') {
              optionsReference = attrOptions;
            }
          } else if (isTextareaType(attrType)) {
            fieldType = 'textarea';
          } else if (attrType === 'readonly') {
            fieldType = 'readonly';
          } else {
            fieldType = 'string';
          }

          return {
            key: attr.name,
            label: attr.label || attr.name,
            type: fieldType,
            required: (attr as any).required || false,
            placeholder: (attr as any).placeholder,
            editable: true, // All fields from backend should be editable in create form
            minRows: isTextareaType(attrType) ? 4 : undefined,
            maxRows: isTextareaType(attrType) ? 8 : undefined,
            options: options,
            optionsReference: optionsReference
          };
        });

      return editableFields;
    }, [attributes, hiddenColumns]);

    // Ensure attributes are loaded
    const ensureAttributesLoaded = useCallback(async () => {
      if (attributes.length === 0) {
        await fetchAttributesData();
      }
    }, [attributes.length, fetchAttributesData]);

    // Load attributes and permissions first, then table data
    useEffect(() => {
      const initializeData = async () => {
        // Load attributes first to ensure columns are available
        await fetchAttributesData();
        await fetchPermissionsData();
        // Then load table data
        await loadTableData();
      };
      initializeData();
    }, [fetchAttributesData, fetchPermissionsData, loadTableData]);

    /**
     * Refetch function compatible with GenericDataHook interface
     */
    const refetch = useCallback(async (params?: {
      page?: number;
      pageSize?: number;
      sort?: Array<{field: string; direction: 'asc' | 'desc'}>;
      filters?: any;
      search?: string;
    }) => {
      await loadTableData(
        params?.page,
        params?.pageSize,
        params?.sort,
        params?.filters,
        params?.search
      );
    }, [loadTableData]);

    return {
      data: tableData,
      loading: isLoadingTableData,
      error: tableDataError,
      refetch,
      pagination: pagination || null,
      columns: generatedColumns,
      // Operations
      handleProjectCreate,
      handleProjectUpdate,
      handleDelete: handleProjectDelete,
      handleDeleteMultiple,
      // FormGenerator specific handlers
      onDelete: handleDeleteSingle,
      onDeleteMultiple: handleDeleteMultiple,
      // Loading states
      editingProjects,
      deletingProjects,
      // Optimistic updates
      updateOptimistically,
      removeOptimistically,
      // Attributes and permissions
      attributes,
      permissions,
      // Functions for EditActionButton
      fetchProjectById,
      ensureAttributesLoaded,
      // Functions for CreateButton
      generateEditFieldsFromAttributes,
      // Entity type
      entityType: 'Projekt'
    };
  };
}

/**
 * Hook factory for Parzellen table with edit/delete/view support
 */
export function createParzellenTableHook(): () => GenericDataHook {
  return () => {
    const [tableData, setTableData] = useState<any[]>([]);
    const [isLoadingTableData, setIsLoadingTableData] = useState(false);
    const [tableDataError, setTableDataError] = useState<string | null>(null);
    const [pagination, setPagination] = useState<TableDataResponse['pagination']>(null);
    const [attributes, setAttributes] = useState<AttributeDefinition[]>([]);
    const [permissions, setPermissions] = useState<UserPermissions | null>(null);
    const [editingParzellen, setEditingParzellen] = useState<Set<string>>(new Set());
    const [deletingParzellen, setDeletingParzellen] = useState<Set<string>>(new Set());
    const [viewingParzellen, setViewingParzellen] = useState<Set<string>>(new Set());
    const { request } = useApiRequest();
    const { checkPermission } = usePermissions();

    // Columns to hide in Parzellen table
    const hiddenColumns = [
      'mandateId', 'Mandate ID', 'Mandat Id',
      'aliasTags', 'Alias Tags',
      'perimeter', 'Perimeter',
      'baulinie', 'Baulinie',
      'bauzone', 'Bauzone',
      'az', 'Az', 'AZ',
      'bz', 'Bz', 'BZ',
      'vollgeschossZahl', 'Vollgeschoss Zahl',
      'anrechenbarDachgeschoss', 'Anrechenbar Dachgeschoss',
      'anrechenbarUntergeschoss', 'Anrechendbar Untergeschoss',
      'gebaudehoheMax', 'Gebäudehöhe Max',
      'regelnGrenzabstand', 'Regeln Grenzabstand',
      'regelnMehrhoehenzuschlag', 'Regln Mehrhoehenzuschlag',
      'parzelleBebaut', 'Parzelle Bebaut',
      'parzelleErschlossen', 'Parzelle Erschlossen',
      'parzelleHanglage', 'Parzelle Hanglage',
      'laermschutzzone', 'Lärmschutzzone',
      'gebaeudehoeheMax', 'Gebäudehöhe Max',
      'regelnMehrlaengenzuschlag', 'Regeln Mehrlängenzuschlag',
      'hochwasserschutzzone', 'Hochwasserschutzzone',
      'grundwasserschutzzone', 'Grundwasserschutzzone',
      'dokumente', 'Dokumente',
      'kontextInformationen', 'Kontext Informationen'
    ];

    // Fetch attributes from backend
    const fetchAttributesData = useCallback(async () => {
      try {
        const attrs = await fetchAttributes(request, 'Parzelle');
        setAttributes(attrs);
        return attrs;
      } catch (error: any) {
        console.error('Error fetching Parzelle attributes:', error);
        setAttributes([]);
        return [];
      }
    }, [request]);

    // Fetch permissions from backend
    const fetchPermissionsData = useCallback(async () => {
      try {
        const perms = await checkPermission('DATA', 'Parzelle');
        setPermissions(perms);
        return perms;
      } catch (error: any) {
        console.error('Error fetching permissions:', error);
        const defaultPerms: UserPermissions = {
          view: false,
          read: 'n',
          create: 'n',
          update: 'n',
          delete: 'n',
        };
        setPermissions(defaultPerms);
        return defaultPerms;
      }
    }, [checkPermission]);

    // Generate columns from attributes
    const generatedColumns = attributes && attributes.length > 0 
      ? attributesToColumns(attributes, hiddenColumns)
      : undefined;

    /**
     * Load data for the specific table
     */
    const loadTableData = useCallback(async (
      page?: number, 
      pageSize?: number, 
      sort?: Array<{ field: string; direction: 'asc' | 'desc' }>,
      filters?: any,
      search?: string
    ) => {
      setIsLoadingTableData(true);
      setTableDataError(null);

      try {
        const params: any = {};
        
        // Build pagination object
        const paginationObj: any = {
          page: page || 1,
          pageSize: pageSize || 10,
          sort: sort || []
        };

        if (filters) {
          paginationObj.filters = filters;
        }

        if (search) {
          paginationObj.search = search;
        }

        params.pagination = JSON.stringify(paginationObj);

        const response = await api.get(`/api/realestate/table/Parzelle`, { params });
        const data: TableDataResponse = response.data;
        
        setTableData(data.items || []);
        setPagination(data.pagination);
      } catch (err: any) {
        const errorMessage =
          err.response?.data?.detail || err.message || `Fehler beim Laden der Tabelle Parzelle`;
        setTableDataError(errorMessage);
      } finally {
        setIsLoadingTableData(false);
      }
    }, []);

    // Fetch a single parzelle by ID
    const fetchParzelleById = useCallback(async (id: string): Promise<any | null> => {
      try {
        // Load all parzellen and find the one with matching ID
        const response = await api.get(`/api/realestate/table/Parzelle`);
        const data: TableDataResponse = response.data;
        const parzelle = (data.items || []).find((item: any) => item.id === id || item.id?.toString() === id);
        return parzelle || null;
      } catch (err: any) {
        console.error('Error fetching parzelle by ID:', err);
        return null;
      }
    }, []);

    // Update parzelle
    const handleParzelleUpdate = useCallback(async (id: string, updateData: any): Promise<{ success: boolean }> => {
      try {
        setEditingParzellen(prev => new Set(prev).add(id));
        
        // Use command API for update
        const response = await api.post('/api/realestate/command', {
          userInput: `UPDATE Parzelle ${id} with ${JSON.stringify(updateData)}`
        });

        const data: CommandResponse = response.data;
        
        if (data.success) {
          // Refetch table data
          await loadTableData();
          return { success: true };
        } else {
          return { success: false };
        }
      } catch (err: any) {
        console.error('Error updating parzelle:', err);
        return { success: false };
      } finally {
        setEditingParzellen(prev => {
          const next = new Set(prev);
          next.delete(id);
          return next;
        });
      }
    }, [loadTableData]);

    // Delete parzelle
    const handleParzelleDelete = useCallback(async (id: string): Promise<boolean> => {
      try {
        setDeletingParzellen(prev => new Set(prev).add(id));
        
        // Use command API for delete
        const response = await api.post('/api/realestate/command', {
          userInput: `DELETE Parzelle ${id}`
        });

        const data: CommandResponse = response.data;
        
        if (data.success) {
          // Refetch table data
          await loadTableData();
          return true;
        } else {
          return false;
        }
      } catch (err: any) {
        console.error('Error deleting parzelle:', err);
        return false;
      } finally {
        setDeletingParzellen(prev => {
          const next = new Set(prev);
          next.delete(id);
          return next;
        });
      }
    }, [loadTableData]);

    // View parzelle (for preview/details)
    const handleParzelleView = useCallback(async (parzelle: any): Promise<void> => {
      const id = parzelle.id || parzelle.id?.toString();
      if (id) {
        setViewingParzellen(prev => new Set(prev).add(id));
        // The actual viewing is handled by the ViewActionButton component
        // This is just for tracking loading state
      }
    }, []);

    // Optimistic update
    const updateOptimistically = useCallback((id: string, updateData: any) => {
      setTableData(prev => prev.map(item => {
        if (item.id === id || item.id?.toString() === id) {
          return { ...item, ...updateData };
        }
        return item;
      }));
    }, []);

    // Optimistic remove
    const removeOptimistically = useCallback((id: string) => {
      setTableData(prev => prev.filter(item => item.id !== id && item.id?.toString() !== id));
    }, []);

    // Ensure attributes are loaded
    const ensureAttributesLoaded = useCallback(async () => {
      if (attributes.length === 0) {
        await fetchAttributesData();
      }
    }, [attributes.length, fetchAttributesData]);

    // Load table data and attributes on mount
    useEffect(() => {
      const initializeData = async () => {
        // Load attributes first to ensure columns are available
        await fetchAttributesData();
        await fetchPermissionsData();
        // Then load table data
        await loadTableData();
      };
      initializeData();
    }, [fetchAttributesData, fetchPermissionsData, loadTableData]);

    /**
     * Refetch function compatible with GenericDataHook interface
     */
    const refetch = useCallback(async (params?: {
      page?: number;
      pageSize?: number;
      sort?: Array<{field: string; direction: 'asc' | 'desc'}>;
      filters?: any;
      search?: string;
    }) => {
      await loadTableData(
        params?.page,
        params?.pageSize,
        params?.sort,
        params?.filters,
        params?.search
      );
    }, [loadTableData]);

    // Handle single parzelle deletion for FormGenerator
    const handleDeleteSingle = useCallback(async (parzelle: any) => {
      const success = await handleParzelleDelete(parzelle.id);
      
      if (success) {
        await loadTableData();
      }
    }, [handleParzelleDelete, loadTableData]);

    // Handle multiple parzelle deletion for FormGenerator
    const handleDeleteMultiple = useCallback(async (selectedParzellen: any[]) => {
      const parzelleIds = selectedParzellen.map(parzelle => parzelle.id);
      
      // Delete all parzellen sequentially
      const results = await Promise.all(
        parzelleIds.map(id => handleParzelleDelete(id))
      );
      
      const allSuccessful = results.every(result => result);
      
      if (allSuccessful) {
        await loadTableData();
      }
    }, [handleParzelleDelete, loadTableData]);

    return {
      data: tableData,
      loading: isLoadingTableData,
      error: tableDataError,
      refetch,
      pagination: pagination || null,
      columns: generatedColumns,
      // Operations
      handleParzelleUpdate,
      handleDelete: handleParzelleDelete,
      handleDeleteMultiple,
      handleParzelleView,
      // FormGenerator specific handlers
      onDelete: handleDeleteSingle,
      onDeleteMultiple: handleDeleteMultiple,
      // Loading states
      editingParzellen,
      deletingParzellen,
      viewingParzellen,
      // Optimistic updates
      updateOptimistically,
      removeOptimistically,
      // Attributes and permissions
      attributes,
      permissions,
      // Functions for EditActionButton
      fetchParzelleById,
      ensureAttributesLoaded,
      // Entity type
      entityType: 'Parzelle'
    };
  };
}

