import { default as cn } from 'classnames';
import { default as default_2 } from 'react';
import { FC } from 'react';
import { Icon } from 'semantic-ui-react';
import { Label } from 'semantic-ui-react';

/**
 * Represents an individual bucket in an aggregation.
 * This is the base bucket data from the API.
 */
export declare interface AggregationBucket {
    key: string;
    doc_count: number;
}

/**
 * Represents the configuration for an aggregation.
 */
export declare interface AggregationConfig {
    field: string;
    aggName: string;
    childAgg?: AggregationConfig;
}

/**
 * Represents aggregation data structure from the API.
 */
export declare interface AggregationData {
    buckets: AggregationBucket[];
}

/**
 * Map of aggregation results from the API.
 */
export declare interface Aggregations {
    [key: string]: AggregationData;
}

/**
 * Extended bucket with UI state information.
 * Used by aggregation components for display and interaction.
 */
export declare interface Bucket extends AggregationBucket {
    label: string;
    is_selected: boolean;
}

export declare const BulkImporter: {
    ExportRecordButton: FC<ExportRecordButtonProps>;
    ExportSearchResultsButton: FC<ExportSearchResultsButtonProps>;
    Search: FC<SearchProps>;
    TaskDetails: FC<TaskDetailsProps>;
};

/**
 * Capitalizes the first letter of a given string.
 *
 * @param string - The input string to capitalize
 * @returns The string with the first letter capitalized, or an empty string if input is null/undefined
 */
export declare const capitalizeFirstLetter: (string: string) => string;

export { cn }

/**
 * Creates a new InvenioSearchApi instance with the provided configuration.
 *
 * @param config - The configuration object for the search API
 * @returns A new InvenioSearchApi instance
 */
export declare const createSearchApi: (config: SearchApiConfig) => unknown;

/**
 * Creates a configuration object for the search API with default settings.
 *
 * @param url - The base URL for the search API endpoint
 * @param headers - Additional HTTP headers to include in requests. Defaults to an empty object
 * @param withCredentials - Whether to include credentials (cookies, authorization headers) in cross-origin requests. Defaults to true
 * @returns A SearchApiConfig object containing axios configuration with the specified parameters
 */
export declare const createSearchApiConfig: (url: string, headers?: Record<string, string>, withCredentials?: boolean) => SearchApiConfig;

/** Default sort option used when the query string is empty. */
export declare interface DefaultSortingOption {
    /** Sort key sent to the API. */
    sortBy: string;
}

/** Triggers a browser download for an in-memory Blob. */
export declare const downloadBlob: (blob: Blob, filename: string) => void;

/** Renders a button that exports a single Invenio record as CSV. */
export declare const ExportRecordButton: default_2.FC<ExportRecordButtonProps>;

/** Props for rendering a single-record CSV export button. */
export declare interface ExportRecordButtonProps extends RecordsExportButtonBaseProps {
    /** Invenio record ID to export. */
    recordId?: string | null;
}

/** Renders a button that exports the current records search as CSV. */
export declare const ExportSearchResultsButton: default_2.FC<ExportSearchResultsButtonProps>;

/** Props for rendering a search-results CSV export button. */
export declare interface ExportSearchResultsButtonProps extends RecordsExportButtonBaseProps {
}

export declare const FileUploader: default_2.FC<FileUploaderProps>;

export declare interface FileUploaderProps {
    taskId?: string;
    value?: File[];
    onChange: (files: File[]) => void;
    accept?: string;
    maxFiles?: number;
    maxTotalSize?: number;
    skipEmptyFiles?: boolean;
    disabled?: boolean;
    error?: string;
}

export declare interface FileUploadProgress {
    fileName: string;
    loaded: number;
    total: number;
    percentage: number;
}

/**
 * Represents a filter value in the search.
 */
export declare interface FilterValue {
    field: string;
    value: string;
    label?: string;
}

export declare const formatDate: (dateString: string) => string;

/**
 * Normalizes task field values for display in the UI.
 *
 * @param value - The raw task value to render.
 * @param formatter - Optional formatter for string-like values.
 * @returns A human-readable string suitable for UI display.
 */
export declare const formatDetailValue: (value?: string | number | boolean | null, formatter?: (value: string) => string) => string;

/**
 * Formats the total size of selected files into a human-readable string.
 * Uses binary prefixes (Bytes, KB, MB, GB) for formatting.
 * @param bytes - The total size in bytes.
 * @return A formatted string representing the file size.
 */
export declare const formatFileSize: (bytes: number) => string;

/**
 * Formats an internal task option key into a human-readable label.
 *
 * @param optionKey - The raw option key, typically snake_case.
 * @returns A UI-friendly label for the option.
 */
export declare const formatOptionLabel: (optionKey: string) => string;

/**
 * Retrieves the CSRF token from browser cookies.
 *
 * This function looks for a cookie named 'csrftoken' and returns its value.
 * CSRF tokens are commonly used to prevent Cross-Site Request Forgery attacks
 * by ensuring that requests originate from the intended source.
 *
 * @returns The CSRF token string if found in cookies, otherwise null
 *
 */
export declare const getCsrfToken: () => string | null;

export declare const getStatusColor: (status: InvenioImporterTaskStates | InvenioImporterRecordStates) => "green" | "red" | "blue" | "yellow" | "grey";

/**
 * Returns ordered task option entries suitable for deterministic rendering.
 *
 * @param options - Task options to read.
 * @returns Known task options in canonical display order.
 */
export declare const getTaskOptionEntries: (options?: TaskOptions | null) => [TaskOptionKey, boolean][];

export declare const getTotalSize: (uploadedFiles: UploadableFile[]) => number;

export declare const getTotalSizeFormatted: (uploadedFiles: UploadableFile[]) => string;

export declare interface ImporterTaskConfig {
    serializers: string[];
    options: TaskOptions;
}

export declare const ImporterTaskStates: {
    readonly CREATED: "created";
    readonly VALIDATING: "validating";
    readonly VALIDATION_FAILED: "validated with failures";
    readonly VALIDATED: "validated";
    readonly IMPORTING: "importing";
    readonly IMPORT_FAILED: "imported with failures";
    readonly SUCCESS: "success";
    readonly DAMAGED: "damaged";
};

export declare const ImportModal: () => default_2.JSX.Element;

/** Initial React-SearchKit query state. */
export declare interface InitialQueryState {
    /** Selected facet filters. */
    filters?: unknown[];
    /** Hidden filters always sent with the query. */
    hiddenParams?: unknown | null;
    /** Active result layout. */
    layout?: string;
    /** Active page number. */
    page?: number;
    /** Number of results per page. */
    size?: number;
    /** Active sort key. */
    sortBy?: string;
    /** Free-text search query. */
    queryString?: string;
}

export declare interface InvenioImporterRecord {
    id: string;
    created: string;
    updated: string;
    links: {
        self: string;
        self_html: string;
        edit_html: string;
        metadata: string;
    };
    revision_id: number;
    status: InvenioImporterRecordStates;
    src_data: {
        id: string;
        doi: string;
        title: string;
        version: string;
        keywords: string;
        filenames: string;
        publisher: string;
        'rights.id': string;
        communities: string;
        description: string;
        'access.files': string;
        'imprint.isbn': string;
        'languages.id': string;
        'rights.title': string;
        'creators.name': string;
        'creators.type': string;
        'imprint.pages': string;
        'imprint.place': string;
        'locations.lat': string;
        'locations.lon': string;
        'imprint.volume': string;
        'imprint.edition': string;
        'locations.place': string;
        'subjects.scheme': string;
        'creators.role.id': string;
        publication_date: string;
        'resource_type.id': string;
        'subjects.subject': string;
        'contributors.name': string;
        'contributors.type': string;
        'identifiers.scheme': string;
        'Imprint.series_name': string;
        'creators.given_name': string;
        'access.embargo.until': string;
        'contributors.role.id': string;
        'creators.family_name': string;
        'references.reference': string;
        'access.embargo.active': string;
        'access.embargo.reason': string;
        'locations.description': string;
        'identifiers.identifier': string;
        'contributors.given_name': string;
        'contributors.family_name': string;
        'creators.affiliations.id': string;
        'creators.identifiers.gnd': string;
        'creators.identifiers.ror': string;
        'creators.identifiers.isni': string;
        'creators.affiliations.name': string;
        'creators.identifiers.orcid': string;
        'related_identifiers.scheme': string;
        'contributors.affiliations.id': string;
        'contributors.identifiers.gnd': string;
        'contributors.identifiers.ror': string;
        'additional_descriptions.notes': string;
        'contributors.identifiers.isni': string;
        'contributors.affiliations.name': string;
        'contributors.identifiers.orcid': string;
        'related_identifiers.identifier': string;
        'additional_descriptions.abstract': string;
        'additional_descriptions.methods.eng': string;
        'related_identifiers.relation_type.id': string;
        'related_identifiers.resource_type.id': string;
        'additional_titles.alternative-title.eng': string;
    };
    errors: Array<{
        msg: string;
        loc: string;
        type: string;
    }>;
    task: {
        id: string;
    };
    generated_record_id?: string;
    serializer_data?: {
        files?: {
            enabled: boolean;
        };
        access?: {
            files: string;
            record: string;
        };
        metadata?: {
            title: string;
            rights?: Array<{
                id: string;
            }>;
            version?: string;
            creators?: Array<{
                affiliations?: Array<{
                    name: string;
                }>;
                person_or_org?: {
                    type: string;
                    given_name: string;
                    family_name: string;
                    identifiers?: Array<{
                        scheme: string;
                        identifier: string;
                    }>;
                };
            }>;
            languages?: Array<{
                id: string;
            }>;
            publisher?: string;
            description?: string;
            contributors?: Array<{
                role?: {
                    id: string;
                };
                affiliations?: Array<{
                    name: string;
                }>;
                person_or_org?: {
                    type: string;
                    given_name: string;
                    family_name: string;
                    identifiers?: Array<{
                        scheme: string;
                        identifier: string;
                    }>;
                };
            }>;
            resource_type?: {
                id: string;
            };
            publication_date?: string;
            additional_descriptions?: Array<{
                lang?: {
                    id: string;
                };
                type?: {
                    id: string;
                };
                description: string;
            }>;
        };
    };
    transformed_data?: {
        files?: {
            enabled: boolean;
        };
        access?: {
            files: string;
            record: string;
        };
        $schema?: string;
        metadata?: {
            title: string;
            rights?: Array<{
                id: string;
            }>;
            version?: string;
            creators?: Array<{
                affiliations?: Array<{
                    name: string;
                }>;
                person_or_org?: {
                    name: string;
                    type: string;
                    given_name: string;
                    family_name: string;
                    identifiers?: Array<{
                        scheme: string;
                        identifier: string;
                    }>;
                };
            }>;
            languages?: Array<{
                id: string;
            }>;
            publisher?: string;
            description?: string;
            contributors?: Array<{
                role?: {
                    id: string;
                };
                affiliations?: Array<{
                    name: string;
                }>;
                person_or_org?: {
                    name: string;
                    type: string;
                    given_name: string;
                    family_name: string;
                    identifiers?: Array<{
                        scheme: string;
                        identifier: string;
                    }>;
                };
            }>;
            resource_type?: {
                id: string;
            };
            publication_date?: string;
            additional_descriptions?: Array<{
                lang?: {
                    id: string;
                };
                type?: {
                    id: string;
                };
                description: string;
            }>;
        };
    };
    community_uuids?: {
        ids: string[];
        default: string;
    };
    record_files?: string[];
    validated_record_files?: Array<{
        key: string;
        size: number;
        origin: string;
        full_path: string;
    }>;
    existing_record_id?: string;
}

export declare interface InvenioImporterRecords {
    hits: {
        hits: InvenioImporterRecord[];
        total: number;
    };
}

export declare type InvenioImporterRecordStates = (typeof InvenioImporterRecordStatus)[keyof typeof InvenioImporterRecordStatus];

export declare const InvenioImporterRecordStatus: {
    readonly CREATED: "created";
    readonly VALIDATING: "validating";
    readonly SERIALIZER_VALIDATION_FAILED: "serializer validation failed";
    readonly VALIDATION_FAILED: "validation failed";
    readonly VALIDATED: "validated";
    readonly IMPORT_FAILED: "import failed";
    readonly IMPORTED: "success";
};

export declare type InvenioImporterTaskStates = (typeof ImporterTaskStates)[keyof typeof ImporterTaskStates];

export declare interface InvenioNewImportTask {
    title: string;
    description: string;
    mode: 'import' | 'delete';
    status: string;
    startTime?: null;
    endTime?: null;
    recordType: string;
    serializer: string;
    options?: TaskOptions;
}

export declare interface InvenioTask {
    id: string;
    created: string;
    updated: string;
    links: {
        self: string;
        self_html: string;
        edit_html: string;
        metadata: string;
    };
    revision_id: number;
    title: string;
    description: string;
    mode: string;
    record_type: string;
    serializer: string;
    start_time?: string | null;
    end_time?: string | null;
    records_status?: Record<InvenioImporterRecordStates, number> & {
        total_records: number;
    };
    status: InvenioImporterTaskStates;
    files: {
        enabled: boolean;
    };
    started_by: {
        id: number;
        username: string | null;
        email: string;
    };
    options: TaskOptions;
}

declare interface LabelProps extends default_2.ComponentProps<typeof Label> {
    status: InvenioTask['status'] | InvenioImporterRecordStates;
}

/** Enabled search result layout modes. */
export declare interface LayoutOptions {
    /** Whether grid view is available. */
    gridView: boolean;
    /** Whether list view is available. */
    listView: boolean;
}

/**
 * Converts a raw API option key into a supported canonical task option key.
 *
 * @param optionKey - Raw option key from the API or form state.
 * @returns The canonical option key when supported, otherwise `null`.
 */
export declare const normalizeTaskOptionKey: (optionKey: string) => TaskOptionKey | null;

export declare type OrchestrationSteps = (typeof OrchestrationStepsEnum)[keyof typeof OrchestrationStepsEnum];

export declare const OrchestrationStepsEnum: {
    readonly CREATING_TASK: "Creating Task";
    readonly UPLOADING_METADATA: "Uploading Metadata";
    readonly UPLOADING_FILES: "Uploading Files";
    readonly UPDATING_METADATA: "Updating Metadata";
    readonly UPDATING_FILES: "Updating Files";
    readonly VALIDATING: "Validating";
    readonly EXECUTING: "Executing";
    readonly UPDATING: "Updating";
};

export declare interface OverridableComponents {
    [key: string]: default_2.ComponentType<unknown>;
}

export declare interface OverridableComponentsTyped<T = Record<string, unknown>> {
    [key: string]: default_2.ComponentType<T>;
}

/** Pagination configuration for search results. */
export declare interface PaginationOptions {
    /** Default selected page size. */
    defaultValue: number;
    /** Maximum number of results SearchKit can page through. */
    maxTotalResults: number;
    /** Available page size options. */
    resultsPerPage: ResultsPerPageOption[];
}

export declare const ProgressLoading: ({ progress, showPercentage }: ProgressLoadingProps) => default_2.JSX.Element;

declare interface ProgressLoadingProps {
    progress: Record<OrchestrationSteps, number>;
    showPercentage?: boolean;
}

/**
 * Represents the query filters applied to the search.
 */
export declare interface QueryFilters {
    [fieldName: string]: FilterValue[] | FilterValue;
}

/** CSV export API configuration for records search. */
export declare interface RecordsExportApiConfig {
    /** Primary Accept header or ordered headers for export requests. */
    accept: string | string[];
    /** Additional Accept headers retried after 406 responses. */
    fallbackAccepts?: string[];
    /** Download filename used when the API does not provide one. */
    filename: string;
    /** Additional headers sent with the export request. */
    headers?: Record<string, string>;
    /** Whether exports should include current pagination params. */
    includePagination: boolean;
    /** Records API URL used for search exports. */
    url: string;
}

/** Options shared by single-record and search-result CSV export requests. */
declare interface RecordsExportApiOptions {
    /** Primary Accept header or ordered list of Accept headers to try first. */
    accept?: string | string[];
    /** Additional Accept headers to retry when the API rejects a media type. */
    fallbackAccepts?: string[];
    /** Download filename to use when the API does not provide one. */
    filename?: string;
    /** Additional request headers to send with the export request. */
    headers?: Record<string, string>;
    /** Records API URL used as the export endpoint. */
    url?: string;
}

/** Shared visual options for CSV export buttons. */
declare interface RecordsExportButtonBaseProps extends RecordsExportApiOptions {
    /** Whether the Semantic UI button should use basic styling. */
    basic?: boolean;
    /** Additional CSS class name applied to the button. */
    className?: string;
    /** Whether the Semantic UI button should use compact spacing. */
    compact?: boolean;
    /** Visible button label shown when iconOnly is false. */
    content?: string;
    /** Whether the export button is disabled. */
    disabled?: boolean;
    /** Whether to render only the export icon. */
    iconOnly?: boolean;
    /** Whether search exports should include current pagination params. */
    includePagination?: boolean;
    /** React-SearchKit query state used by search-result export. */
    queryState?: Record<string, unknown>;
    /** Semantic UI button size. */
    size?: 'mini' | 'tiny' | 'small' | 'medium' | 'large';
    /** Tooltip text shown when the export button has no error. */
    title?: string;
}

/** Results-per-page dropdown option. */
export declare interface ResultsPerPageOption {
    /** Human-readable option label. */
    text: string;
    /** Page size value sent to SearchKit. */
    value: number;
}

/**
 * Removes unsupported or malformed task option entries from an unknown input.
 *
 * @param options - Raw options payload from the API or form state.
 * @returns A sanitized task options object containing only known boolean flags.
 */
export declare const sanitizeTaskOptions: (options: unknown) => TaskOptions;

/** Renders the reusable SearchKit-powered importer search UI. */
export declare const Search: default_2.FC<SearchProps>;

/** Axios configuration used by the SearchKit API client. */
export declare interface SearchApiConfig {
    /** Axios request options for the search endpoint. */
    axios: {
        /** Headers sent with each search request. */
        headers?: Record<string, string>;
        /** Search endpoint URL. */
        url?: string;
        /** Whether requests should include browser credentials. */
        withCredentials?: boolean;
    };
    /** Invenio-specific SearchKit serializer configuration. */
    invenio?: {
        /** Name of the request serializer used by React-SearchKit. */
        requestSerializer?: string;
    };
}

/** Search API config override accepted by the Search component. */
declare type SearchApiConfigOverride = Partial<Omit<SearchApiConfig, 'axios'>> & {
    /** Partial Axios config merged with the default SearchKit Axios config. */
    axios?: Partial<SearchApiConfig['axios']>;
};

/** Full configuration object for the reusable search UI. */
export declare interface SearchConfig {
    /** Facet aggregation configuration consumed by SearchKit. */
    aggs: unknown[];
    /** SearchKit application ID used for overridable component keys. */
    appId: string;
    /** Sort options used before the user enters a query. */
    defaultSortingOnEmptyQueryString: DefaultSortingOption[];
    /** Records CSV export configuration. */
    exportApi: RecordsExportApiConfig;
    /** Initial SearchKit query state. */
    initialQueryState: InitialQueryState;
    /** Enabled result layout modes. */
    layoutOptions: LayoutOptions;
    /** Pagination and page-size configuration. */
    paginationOptions: PaginationOptions;
    /** Base UI route used for task detail links. */
    resultPath: string;
    /** Search API configuration. */
    searchApi: SearchApiConfig;
    /** Sort dropdown options. */
    sortOptions: SortOption[];
    /** Whether manual sort direction controls are disabled. */
    sortOrderDisabled: boolean;
    /** Whether to render the search-level CSV export button. */
    showExportButton?: boolean;
    /** Whether to render facet filters. */
    showFacets?: boolean;
    /** Whether to render the new import modal trigger. */
    showImportModal?: boolean;
    /** Whether to render pagination and page-size controls. */
    showSearchFooter?: boolean;
}

/** Partial search config accepted by the Search component. */
export declare type SearchConfigOverride = Partial<Omit<SearchConfig, 'exportApi' | 'searchApi'>> & {
    /** Partial CSV export config merged with the default export config. */
    exportApi?: Partial<RecordsExportApiConfig>;
    /** Partial search API config merged with the default search API config. */
    searchApi?: SearchApiConfigOverride;
};

/** Props for rendering the reusable Search component. */
export declare interface SearchProps {
    /** Optional search configuration overrides. */
    config?: SearchConfigOverride;
    /** Optional component override registry for react-overridable. */
    overriddenComponents?: OverridableComponents;
}

/**
 * Search results data structure from the API.
 */
export declare interface SearchResultsData {
    aggregations?: Aggregations;
    hits?: unknown[];
    total?: number;
}

/** Sort option shown in the search sort dropdown. */
export declare interface SortOption {
    /** Sort key sent to the API. */
    sortBy: string;
    /** Human-readable sort option label. */
    text: string;
}

export declare const Spinner: () => default_2.JSX.Element;

export declare const StatusIcon: default_2.FC<StatusIconProps>;

declare interface StatusIconProps extends default_2.ComponentProps<typeof Icon> {
    status: InvenioTask['status'] | InvenioImporterRecordStates;
}

export declare const StatusLabel: default_2.FC<LabelProps>;

/**
 * Canonical task option keys supported by the UI and API payloads.
 *
 * This list is used as the single source of truth for typing, sanitization,
 * and ordered rendering of task options across the application.
 */
export declare const TASK_OPTION_KEYS: readonly ["doi_minting", "publish"];

export declare const TaskConfiguration: default_2.FC<TaskConfigurationProps>;

declare interface TaskConfigurationProps {
    task: InvenioTask;
}

export declare const TaskDetails: default_2.FC<TaskDetailsProps>;

export declare interface TaskDetailsProps {
    taskId: string;
}

export declare const TaskHeader: default_2.FC<TaskHeaderProps>;

declare interface TaskHeaderProps {
    task: InvenioTask;
    totalRecords: number;
    validatedRecords: number;
    errorRecords: number;
    successRecords: number;
    isRefreshing: boolean;
    isRunningTask: boolean;
    onRefresh: () => void;
    onRunTask: () => Promise<void>;
}

/**
 * Union of supported task option keys.
 */
export declare type TaskOptionKey = (typeof TASK_OPTION_KEYS)[number];

/**
 * Task option flags accepted by the importer.
 *
 * The shape is partial because the API may omit options that are not available
 * for a given record type.
 */
export declare type TaskOptions = Partial<Record<TaskOptionKey, boolean>>;

export declare interface TaskOrchestrationOptions {
    autoValidate?: boolean;
    autoExecute?: boolean;
    onProgress?: (step: OrchestrationSteps, progress?: number) => void;
    onError?: (error: Error, step: OrchestrationSteps) => void;
}

export declare const TaskRecordItem: default_2.FC<TaskRecordItemProps>;

/** Props for rendering a single importer task record row. */
export declare interface TaskRecordItemProps {
    /** Importer record displayed by the table row. */
    result: InvenioImporterRecord;
    /** Row index supplied by React-SearchKit. */
    index: number;
}

export declare interface UploadableFile {
    file: File;
    id: string;
    error?: string;
}

/**
 * Custom hook for managing file uploads.
 * Provides functionality to add, remove, and clear files,
 * along with validation against accepted types and size limits.
 */
export declare const useFileUploader: ({ onUploadError }?: UseFileUploaderProps) => {
    uploadFiles: UploadableFile[];
    isUploading: boolean;
    addFiles: (newFiles: File[], accept?: string, maxFiles?: number, maxTotalSize?: number, skipEmptyFiles?: boolean) => UploadableFile[];
    removeFile: (fileId: string) => void;
    clearFiles: () => void;
};

declare interface UseFileUploaderProps {
    taskId?: string;
    onUploadComplete?: (files: File[]) => void;
    onUploadError?: (error: string) => void;
}

export { }
