/**
 * Table Component Factory
 *
 * Generates entity table components from configuration.
 * Reduces boilerplate in entity-specific table components.
 */

import React from 'react';
import GenericTable from '../Generic/GenericTable';
import type { RootState } from '../../stores/store';
import type { Filter, FilterItem } from '../../types/filters';
import type { GridColDef } from '@mui/x-data-grid';
import type { AsyncThunk } from '@reduxjs/toolkit';
import type { NotificationState } from '../../types/redux';
import type { BaseEntity } from '../../types/entities';

/**
 * Entity slice state shape - matches InternalSliceState from createEntitySlice
 */
interface EntitySliceState<T> {
  [key: string]: T[] | boolean | number | NotificationState | unknown[];
  loading: boolean;
  count: number;
  refetch: boolean;
  notify: NotificationState;
}

/**
 * Configuration for creating a table component
 */
export interface TableComponentConfig<T extends BaseEntity> {
  /** Entity name (e.g., 'roles', 'users') */
  entityName: string;
  /** Redux slice selector */
  sliceSelector: (state: RootState) => EntitySliceState<T>;
  /** Fetch action thunk */
  fetchAction: AsyncThunk<
    T | { rows: T[]; count: number },
    { id?: string; query?: string },
    object
  >;
  /** Update action thunk */
  updateAction: AsyncThunk<T, { id: string; data: Partial<T> }, object>;
  /** Delete single item action thunk */
  deleteAction: AsyncThunk<void, string, object>;
  /** Delete multiple items action thunk */
  deleteByIdsAction: AsyncThunk<void, string[], object>;
  /** Set refetch flag action */
  setRefetchAction: (refetch: boolean) => { type: string; payload: boolean };
  /** Column loader function */
  loadColumnsFunction: (
    onDelete: (id: string) => void,
    entityName: string,
    user: unknown,
  ) => Promise<GridColDef[]>;
}

/**
 * Props for generated table components
 */
export interface TableComponentProps {
  filterItems: FilterItem[];
  setFilterItems: (items: FilterItem[]) => void;
  filters: Filter[];
  showGrid?: boolean;
}

/**
 * Create a table component from configuration
 *
 * @example
 * import { fetch, update, deleteItem, setRefetch, deleteItemsByIds } from '../../stores/roles/rolesSlice';
 * import { loadColumns } from './configureRolesCols';
 *
 * const TableRoles = createTableComponent<Role>({
 *   entityName: 'roles',
 *   sliceSelector: (state) => state.roles,
 *   fetchAction: fetch,
 *   updateAction: update,
 *   deleteAction: deleteItem,
 *   deleteByIdsAction: deleteItemsByIds,
 *   setRefetchAction: setRefetch,
 *   loadColumnsFunction: loadColumns,
 * });
 *
 * export default TableRoles;
 */
export function createTableComponent<T extends BaseEntity>(
  config: TableComponentConfig<T>,
): React.FC<TableComponentProps> {
  const TableComponent: React.FC<TableComponentProps> = ({
    filterItems,
    setFilterItems,
    filters,
  }) => {
    return (
      <GenericTable<T>
        entityName={config.entityName}
        sliceSelector={config.sliceSelector}
        fetchAction={config.fetchAction}
        updateAction={config.updateAction}
        deleteAction={config.deleteAction}
        deleteByIdsAction={config.deleteByIdsAction}
        setRefetchAction={config.setRefetchAction}
        loadColumnsFunction={config.loadColumnsFunction}
        filters={filters}
        filterItems={filterItems}
        setFilterItems={setFilterItems}
      />
    );
  };

  TableComponent.displayName = `Table${config.entityName.charAt(0).toUpperCase() + config.entityName.slice(1)}`;

  return TableComponent;
}

export default createTableComponent;
