import React from 'react';
import { IconType } from 'react-icons';
import { DragDropConfig } from '../../components/UiComponents/DragDropOverlay/DragDropOverlay';

// Generic privilege checker function type
export type PrivilegeChecker = () => boolean | Promise<boolean>;

// Form field configuration for create/edit buttons
export interface ButtonFormField {
    key: string;
    label: string | LanguageText;
    type: 'string' | 'boolean' | 'email' | 'textarea' | 'date' | 'enum' | 'readonly' | 'multiselect' | 'number';
    required?: boolean;
    placeholder?: string | LanguageText;
    minRows?: number;
    maxRows?: number;
    validator?: (value: any) => string | null;
    defaultValue?: any;
    options?: string[] | Array<{ value: string | number; label: string }>; // For enum/multiselect fields
    optionsReference?: string; // Reference to a data source for dynamic options (e.g., 'TrusteeOrganisation', 'User')
}

// Dropdown configuration for header dropdown buttons
export interface DropdownConfig<T = any> {
    type: 'dropdown';
    items: Array<{
        id: string | number;
        label: string | LanguageText;
        value: T;
        metadata?: Record<string, any>;
    }>;
    selectedItemId?: string | number | null;
    onSelect: (item: { id: string | number; label: string | LanguageText; value: T; metadata?: Record<string, any> } | null, hookData?: any) => void | Promise<void>;
    placeholder?: string | LanguageText;
    emptyMessage?: string | LanguageText;
    headerText?: string | LanguageText;
    // Optional: name of property in hookData that provides items, selectedItemId, and onSelect
    dataSource?: {
        itemsProperty?: string; // Property name in hookData that contains items array
        selectedIdProperty?: string; // Property name in hookData that contains selectedItemId
        onSelectMethod?: string; // Method name in hookData for onSelect callback
        loadingProperty?: string; // Property name in hookData that contains loading state
    };
}

// Button configuration for header actions
export interface PageButton {
    id: string;
    label: string | LanguageText;
    variant?: 'primary' | 'secondary' | 'danger' | 'success' | 'warning';
    size?: 'sm' | 'md' | 'lg';
    icon?: IconType;
    onClick?: (hookData?: any) => void | Promise<void>;
    disabled?: boolean | ((hookData?: any) => boolean | { disabled: boolean; message?: string });
    // Form configuration for create buttons
    formConfig?: {
        fields: ButtonFormField[];
        popupTitle?: string | LanguageText;
        popupSize?: 'small' | 'medium' | 'large';
        createOperationName?: string; // Name of the create operation in hookData (e.g., 'handlePromptCreate')
        successMessage?: string | LanguageText;
        errorMessage?: string | LanguageText;
        multiStep?: boolean; // Enable multi-step form mode
    };
    // Dropdown configuration for dropdown selection buttons
    dropdownConfig?: DropdownConfig;
}

// Input form configuration
export interface InputFormConfig {
    hookFactory?: () => () => GenericDataHook; // Optional, can use page-level hook from tableConfig if exists
    placeholder?: string | LanguageText;
    buttonLabel?: string | LanguageText;
    stopButtonLabel?: string | LanguageText; // Label for stop button when workflow is running
    buttonIcon?: IconType;
    stopButtonIcon?: IconType; // Icon for stop button when workflow is running
    buttonVariant?: 'primary' | 'secondary' | 'danger' | 'success' | 'warning';
    stopButtonVariant?: 'primary' | 'secondary' | 'danger' | 'success' | 'warning'; // Variant for stop button
    buttonSize?: 'sm' | 'md' | 'lg';
    textFieldSize?: 'sm' | 'md' | 'lg';
    showFileUpload?: boolean; // Whether to show file upload button (default: true if hook provides file upload)
}

// Settings field configuration
export interface SettingsFieldConfig {
    id: string;
    type: 'text' | 'select' | 'toggle';
    label: string | LanguageText;
    description?: string | LanguageText;
    required?: boolean;
    disabled?: boolean | ((data: any) => boolean);
    inputType?: 'text' | 'email' | 'tel';
    placeholder?: string | LanguageText;
    options?: Array<{id: string | number; label: string | LanguageText; value: any}>;
    dataKey: string; // Dot-notation path (e.g., "mandate_general.company_name")
    onSave?: (value: any, data: any) => Promise<void> | void;
}

// Settings section configuration
export interface SettingsSectionConfig {
    id: string;
    title: string | LanguageText;
    description?: string | LanguageText;
    icon?: IconType; // Optional icon for section header
    // Fields will be loaded from backend based on sectionId
    sectionId: string; // Identifier sent to backend to fetch fields
    // Save handler per section (uses Button component)
    onSave?: (sectionId: string, data: any) => Promise<void>;
    saveButtonLabel?: string | LanguageText;
    saveButtonVariant?: 'primary' | 'secondary' | 'danger' | 'success' | 'warning';
    saveButtonSize?: 'sm' | 'md' | 'lg';
    // Optional: Static field overrides from config (takes precedence over backend)
    staticFields?: SettingsFieldConfig[];
    // Optional: Conditional rendering - if provided, section only renders if condition returns true
    renderCondition?: (formData: any) => boolean;
    // Optional: Alternative content to render when renderCondition returns false
    renderAlternative?: (formData: any, t: (key: string) => string, resolveLanguageText: (text: string | LanguageText, t: (key: string) => string) => string) => React.ReactNode;
}

// Settings configuration
export interface SettingsConfig {
    sections: SettingsSectionConfig[];
    hookFactory?: () => () => GenericDataHook; // For data fetching and field loading
}

// Content section for paragraphs
export interface PageContent {
    id: string;
    type: 'paragraph' | 'heading' | 'list' | 'code' | 'divider' | 'custom' | 'table' | 'inputForm' | 'messages' | 'settings' | 'log' | 'tabs' | 'columns' | 'chatHistory';
    content?: string | LanguageText; // Optional for dividers
    level?: number; // For headings (1-6)
    items?: (string | LanguageText)[]; // For lists
    language?: string; // For code blocks
    customComponent?: React.ComponentType<any>;
    // Table-specific properties
    tableConfig?: TableContentConfig;
    // Input form-specific properties
    inputFormConfig?: InputFormConfig;
    // Messages-specific properties
    messagesConfig?: {
        variant?: 'chat' | 'log'; // Message display variant: 'chat' for bubble UI, 'log' for list/table UI
        dataSource?: 'messages' | 'logs' | 'both'; // Data source to render: 'messages' (default), 'logs', or 'both' (logs use log variant when merged)
        showDocuments?: boolean;
        showMetadata?: boolean;
        showProgress?: boolean;
        emptyMessage?: string | LanguageText;
    };
    // Settings-specific properties
    settingsConfig?: SettingsConfig;
    // Log-specific properties
    logConfig?: {
        emptyMessage?: string | LanguageText;
    };
    // Chat history-specific properties
    chatHistoryConfig?: {
        emptyMessage?: string | LanguageText;
    };
    // Tabs-specific properties
    tabsConfig?: {
        tabs: Array<{
            id: string;
            label: string | LanguageText;
            content: PageContent[]; // Nested content sections for each tab
        }>;
        defaultTabId?: string;
    };
    // Columns-specific properties
    columnsConfig?: {
        columns: Array<{
            id: string;
            width?: string; // CSS width (e.g., "3fr", "1fr", "75%", "25%")
            content: PageContent[]; // Nested content sections for each column
        }>;
        gap?: string; // CSS gap value
    };
}

// Generic hook interface for data fetching
export interface GenericDataHook {
    data: any[];
    loading: boolean;
    isRefetching?: boolean; // True when refetching data (keeps existing data visible)
    error: string | null;
    refetch?: (params?: { page?: number; pageSize?: number; sort?: Array<{field: string; direction: 'asc' | 'desc'}>; filters?: any; search?: string }) => Promise<void>;
    pagination?: {
        currentPage: number;
        pageSize: number;
        totalItems: number;
        totalPages: number;
        sort?: Array<{ field: string; direction: 'asc' | 'desc' }>;
        filters?: any;
    } | null;
    removeFileOptimistically?: (fileId: string) => void; // For optimistic updates
    columns?: any[]; // Optional columns configuration
    // File operations
    handleUpload?: (file: File) => Promise<{ success: boolean; data: any }>; // For file upload functionality
    handleFileUpload?: (file: File) => Promise<{ success: boolean; data: any }>; // Alias for handleUpload
    handleDownload?: (fileId: string, fileName: string) => Promise<boolean>; // For file download functionality
    handleDelete?: (fileId: string, onOptimisticDelete?: () => void) => Promise<boolean>; // For file delete functionality
    handleFileDelete?: ((fileId: string, onOptimisticDelete?: () => void) => Promise<boolean>) | ((file: any) => Promise<void>); // Can accept fileId or WorkflowFile
    handlePreview?: (fileId: string, fileName: string, mimeType?: string) => Promise<any>; // For file preview functionality
    // File management properties
    workflowFiles?: any[]; // Files connected to workflow
    pendingFiles?: any[]; // Files pending attachment
    allUserFiles?: any[]; // All user files
    handleFileRemove?: ((fileId: string) => Promise<void> | void) | ((file: any) => Promise<void> | void); // Can accept fileId or WorkflowFile
    handleFileAttach?: (fileId: string) => Promise<void>; // Attach file to workflow (always returns Promise)
    handleFileUploadAndAttach?: (file: File) => Promise<{ success: boolean; data: any }>; // Upload and attach file
    uploadingFile?: boolean; // Loading state for file upload
    deletingFiles?: Set<string>; // Set of file IDs being deleted
    previewingFiles?: Set<string>; // Set of file IDs being previewed
    removingFiles?: Set<string>; // Set of file IDs being removed
    isFileAttachmentPopupOpen?: boolean; // Whether file attachment popup is open
    setIsFileAttachmentPopupOpen?: (open: boolean) => void; // Set file attachment popup state
    // FormGenerator specific handlers
    onDelete?: (row: any) => Promise<void>; // For single item deletion
    onDeleteMultiple?: (rows: any[]) => Promise<void>; // For multiple item deletion
    // Input form operations
    inputValue?: string;
    onInputChange?: (value: string) => void;
    handleSubmit?: () => Promise<void>; // No parameters, uses internal inputValue
    isSubmitting?: boolean;
    // Prompt selector properties
    promptPermission?: {
        view?: boolean;
        read?: string;
    };
    promptItems?: Array<{ id: string | number; label: string; value: any }>;
    selectedPromptId?: string | number | null;
    onPromptSelect?: (item: { id: string | number; label: string; value: any } | null) => void | Promise<void>;
    promptsLoading?: boolean;
    // Workflow mode selector properties
    workflowModeItems?: Array<{ id: string | number; label: string; value: any }>;
    selectedWorkflowMode?: string | number | null;
    onWorkflowModeSelect?: (item: { id: string | number; label: string; value: any } | null) => void | Promise<void>;
    // Workflow lifecycle state
    workflowId?: string;
    workflowStatus?: string;
    workflowData?: {
        currentRound?: number;
        [key: string]: any;
    };
    isRunning?: boolean;
    currentRound?: number; // Current workflow round
    latestStats?: any; // Latest workflow statistics
    // Messages from workflow
    messages?: any[];
    // Logs from workflow
    logs?: any[];
    // Dashboard log tree
    dashboardTree?: any; // Dashboard log tree structure
    onToggleOperationExpanded?: (operationId: string) => void;
    getChildOperations?: (parentId: string | null) => string[];
    // Settings-specific properties
    settingsData?: any; // Unified data object for settings fields
    settingsFields?: Record<string, SettingsFieldConfig[]>; // Field definitions per sectionId
    settingsLoading?: Record<string, boolean>; // Loading state per section
    settingsErrors?: Record<string, string | null>; // Error state per section
    saveSection?: (sectionId: string, data: any) => Promise<void>; // Save handler for a section
    // Dropdown data source loading property
    [key: string]: any; // Allow additional properties for dynamic data sources
}

// Standard action button configuration (built-in actions: edit, delete, view, copy, connect, play)
export interface ActionButtonConfig {
    type: 'view' | 'edit' | 'delete' | 'copy' | 'connect' | 'play';
    onAction?: (row: any) => Promise<void> | void; // Optional for delete buttons since they handle their own logic
    title?: string | LanguageText;
    disabled?: (row: any, hookData?: any) => boolean | { disabled: boolean; message?: string };
    loading?: (row: any, hookData?: any) => boolean;
    // Field mappings for flexible data access
    idField?: string; // Field name for the unique identifier (default: 'id')
    nameField?: string; // Field name for display name (default: 'name' or 'file_name')
    typeField?: string; // Field name for type/mime type (default: 'type' or 'mime_type')
    contentField?: string; // Field name for content (default: 'content')
    statusField?: string; // Field name for status (used by connect action)
    // Operation and loading state names
    operationName?: string; // Name of the operation function in hookData
    loadingStateName?: string; // Name of the loading state in hookData
    fetchItemFunctionName?: string; // Name of the function in hookData to fetch a single item by ID (for edit button)
    // Navigation and mode (for play action)
    navigateTo?: string; // Path to navigate to after action
    mode?: string; // Mode to set (e.g., 'prompt', 'workflow')
}

// Custom action button configuration (for entity-specific actions like download, connect, play, sendPasswordLink)
export interface CustomActionConfig {
    id: string; // Unique identifier for the action
    icon: React.ReactNode; // Icon component to display
    onClick: (row: any, hookData?: any) => Promise<void> | void; // Handler function
    visible?: (row: any, hookData?: any) => boolean; // Show/hide based on row data (default: true)
    disabled?: (row: any, hookData?: any) => boolean | { disabled: boolean; message?: string }; // Disable based on row data
    loading?: (row: any, hookData?: any) => boolean; // Loading state based on row data
    title?: string | LanguageText | ((row: any) => string); // Tooltip text
    className?: string; // Optional custom CSS class
    // Field mappings (optional, for convenience)
    idField?: string; // Field name for the unique identifier (default: 'id')
}

// Table content configuration
export interface TableContentConfig {
    hookFactory: () => () => GenericDataHook; // Hook factory that returns a hook function
    columns?: any[]; // Column configuration (optional - can be generated dynamically from attributes via hookData.columns)
    actionButtons?: ActionButtonConfig[]; // Standard action buttons configuration (edit, delete, view, copy)
    customActions?: CustomActionConfig[]; // Custom action buttons (download, connect, play, sendPasswordLink, etc.)
    searchable?: boolean;
    filterable?: boolean;
    sortable?: boolean;
    resizable?: boolean;
    pagination?: boolean;
    pageSize?: number;
    className?: string;
    emptyMessage?: string; // Custom message to display when table is empty
}

// Language-aware text interface
export interface LanguageText {
    de: string;
    en: string;
    fr: string;
}

// Utility function to resolve language text
export const resolveLanguageText = (text: string | LanguageText | undefined, t?: (key: string, fallback?: string) => string): string => {
    if (!text) return '';
    if (typeof text === 'string') {
        // Always use the translation function for strings (language keys)
        if (t) {
            return t(text);
        }
        return text;
    }
    // For LanguageText objects, we should convert them to language keys
    // For now, fallback to the first available language
    return text.de || text.en || text.fr || '';
};

// Generic page data interface
export interface GenericPageData {
    // Core identification
    id: string;
    path: string;
    name: string;
    description?: string | LanguageText;
    
    // Navigation
    parentPath?: string; // For subpages/subsubpages
    order?: number;
    showInSidebar?: boolean;
    
    // Visual
    icon?: IconType;
    title: string | LanguageText;
    subtitle?: string | LanguageText;
    
    // Header configuration
    headerButtons?: PageButton[];
    
    // Content sections
    content?: PageContent[];
    
    // Page behavior
    persistent?: boolean;
    preserveState?: boolean;
    preload?: boolean;
    moduleEnabled?: boolean;
    hide?: boolean; // If true, page is completely hidden and not rendered
    
    // Subpage support
    hasSubpages?: boolean;
    
    // Lifecycle hooks
    onActivate?: () => void | Promise<void>;
    onDeactivate?: () => void | Promise<void>;
    onLoad?: () => void | Promise<void>;
    onUnload?: () => void | Promise<void>;
    
    // Custom component override (optional)
    customComponent?: React.ComponentType<any>;
    
    // Privilege checker - if provided, page will only render if checker returns true
    privilegeChecker?: PrivilegeChecker;
    
    // Drag and drop configuration
    dragDropConfig?: DragDropConfig;
}

// Page data file structure
export interface PageDataFile {
    page: GenericPageData;
    subpages?: PageDataFile[];
}

// Sidebar item interface for compatibility
export interface SidebarItem {
    id: string;
    name: string;
    link: string | undefined; // Allow undefined for parent groups that aren't clickable pages
    icon?: IconType | React.ComponentType<React.SVGProps<SVGSVGElement>>; // Allow both IconType and SVG components
    moduleEnabled: boolean;
    order: number;
    submenu?: SidebarSubmenuItemData[];
}

// Sidebar submenu item data interface
export interface SidebarSubmenuItemData {
    id: string;
    name: string;
    link: string;
    icon?: IconType;
}

// Page instance for PageManager
export interface PageInstance {
    path: string;
    component: React.ReactElement;
    isActive: boolean;
    shouldPreserve: boolean;
    pageData: GenericPageData;
}

// Page manager props
export interface PageManagerProps {
    loadingComponent: React.ComponentType;
    errorComponent: React.ComponentType;
}
