import { RowData, AccessorKeyColumnDef, Table, ColumnFiltersState, ColumnSort, Cell } from '@tanstack/react-table';
import { SortOrder, CellTypes } from './constants.js';
import { StylesConfig } from 'react-select';
import { PaginationProps } from '../pagination/pagination.js';
import { BaseOption, CustomSelectProps } from '../select/customSelect.js';
import 'react/jsx-runtime';
import '@trail-ui/theme';
import 'react';
import '../overlay/overlay.js';

declare module '@tanstack/react-table' {
    interface TableMeta<TData extends RowData> {
        updateData: (rowIndex: string, columnId: keyof TData | '', value: unknown) => void;
    }
}
type EditableTableColumnDef<TData> = Omit<AccessorKeyColumnDef<TData, any>, 'meta'> & {
    meta?: ColumnMeta<TData>;
    accessorKey: keyof TData | '';
    columnType?: 'td' | 'th';
};
type EditableTableProps<TData> = {
    tableId?: string;
    classNames?: {
        wrapper?: string;
        tableWrapper?: string;
        table?: string;
    };
    tableName: string;
    data: TData[];
    columns: EditableTableColumnDef<TData>[];
    isLoading: boolean;
    handleSaveData: (data: SaveData<TData>) => void;
    idSelector: (data: TData) => string;
    selectAllCheckBoxName?: string;
    setTable?: (table: Table<TData>) => void;
    setColumnFilters?: (value: ColumnFiltersState) => void;
    hiddenColumnIds?: string[];
    isCellDisabled?: (data: TData, column: EditableTableColumnDef<TData>['id']) => boolean;
    showPagination?: boolean;
    serverPagination?: boolean;
    totalCount?: number;
    currentPage?: number;
    onPageChange?: (page: number) => void;
    currentPageSize?: number;
    onPageSizeChange?: (limit: number) => void;
    defaultSortingHeaders?: ColumnSort[];
    handleSort?: (sortData: {
        columnId: string;
        order: SortOrder;
    }) => void;
    globalFilter?: string;
    setGlobalFilter?: (value: any) => void;
    paginationSizeOptions?: PaginationProps['sizeOptions'];
    showTableFooter?: boolean;
    onSelectionChange?: (ids: string[]) => void;
};
type GroupedEditableTableProps<TData> = Omit<EditableTableProps<TData>, 'data'> & {
    data: {
        groupId: string;
        groupName: string;
        data: TData[];
        description?: string;
    }[];
    allowBulkGroupSelection: boolean;
};
type EditableTableCellProps<TData> = {
    cell: Cell<TData, unknown>;
    isCellDisabled?: EditableTableProps<TData>['isCellDisabled'];
};
interface SaveData<TData> {
    rowId: string;
    columnId: string;
    accessorKey: keyof TData | '';
    value: string | number | boolean;
    groupId?: string;
}
type ColumnMeta<TData> = (CheckBoxMetaData<TData> | LinkMetaData | MultiSelectMetaData<TData> | TextInputMetaData<TData> | SelectMetaData<TData> | SwitchMetaData<TData>) & FooterMeta;
interface CheckBoxMetaData<TData> {
    type: 'checkbox';
    label?: (data: TData) => string;
}
interface LinkMetaData {
    type: 'link';
}
interface MultiSelectMetaData<TData> {
    type: 'multiselect';
    placeholder: string;
    label?: (data: TData) => string;
    options: {
        label: string;
        value: string | number;
    }[];
    customStyles?: StylesConfig<MultiSelectMetaData<TData>['options'][0], true>;
}
interface TextInputMetaData<TData> {
    type: 'text' | 'date' | 'number';
    placeholder: string;
    label?: (data: TData) => string;
    step?: number;
}
interface SelectMetaData<TData> {
    type: 'select';
    placeholder: string;
    label?: (data: TData) => string;
    options: BaseOption[];
    renderCustomLabel?: CustomSelectProps['renderCustomLabel'];
}
interface SwitchMetaData<TData> {
    type: 'switch';
    label?: (data: TData) => string;
    activeText?: string;
    inactiveText?: string;
}
interface FooterMeta {
    footerType?: 'addition' | 'average' | 'isTotalField';
}
interface Row<TData> {
    getValue(columnId: string): unknown;
    original: TData;
}
interface FocusData {
    rowId: string | null;
    columnIndex: number;
    cellType: CellTypes;
    groupId: string | null;
    rowIndex: number;
}
interface FocusHandlerContextType {
    focusedCell: FocusData;
    setFocusedCell: (focusData: FocusData) => void;
}
interface TableContextType<TData> {
    handleSaveData: EditableTableProps<TData>['handleSaveData'];
    idSelector: EditableTableProps<TData>['idSelector'];
    table: Table<TData>;
    tableName: string;
    groupData: {
        groupName: string;
        groupId: string;
        ids: string[];
        description?: string;
    }[];
    allowBulkGroupSelection: boolean;
    tableRef: React.RefObject<HTMLTableElement>;
    doesRowHeaderExist: boolean;
    hasFooter: boolean;
    serverPagination: boolean;
}
interface UseFocusHandlerProps {
    cellType: CellTypes;
    rowId: string | null;
    columnIndex: number;
    groupId: string | null;
    rowIndex: number;
}
interface FocusHookReturnType {
    focusedCell: FocusData;
    setFocusedCell: (focusData: FocusData) => void;
    tableRef: React.RefObject<HTMLTableElement>;
    isCurrentCellFocused: boolean;
    focusCurrentCell: () => void;
}
type TDataWithGroupId<TData> = TData & {
    editableTableGroupId: string;
};
interface EditableTablePaginationProps<TData> {
    totalResults: number;
    pagination: {
        pageIndex: number;
        pageSize: number;
    };
    table: Table<TData>;
    onPageChange?: (page: number) => void;
    onPageSizeChange?: (limit: number) => void;
    paginationSizeOptions?: PaginationProps['sizeOptions'];
}

export { CheckBoxMetaData, ColumnMeta, EditableTableCellProps, EditableTableColumnDef, EditableTablePaginationProps, EditableTableProps, FocusData, FocusHandlerContextType, FocusHookReturnType, FooterMeta, GroupedEditableTableProps, LinkMetaData, MultiSelectMetaData, Row, SaveData, SelectMetaData, SwitchMetaData, TDataWithGroupId, TableContextType, TextInputMetaData, UseFocusHandlerProps };
