import { createContext, type ReactNode, useContext } from 'react';
import type { EditableTableColumnDef, TableContextType, TDataWithGroupId } from '../types';
import type { Cell } from '@tanstack/react-table';

export const EditableTableContext = createContext<unknown>({
  handleSaveData: () => {},
  idSelector: () => {},
  table: {},
  tableName: '',
  groupData: [],
  allowBulkGroupSelection: false,
  doesRowHeaderExist: false,
});

interface TableContextProviderProps<TData> extends TableContextType<TData> {
  children: ReactNode;
}

export default function TableContextProvider<TData>({
  children,
  ...props
}: TableContextProviderProps<TData>) {
  return <EditableTableContext.Provider value={props}>{children}</EditableTableContext.Provider>;
}

type UseTableContextBase<TData> = Omit<TableContextType<TData>, 'handleSaveData'>;

type UseTableContextWithCell<TData> = UseTableContextBase<TData> & {
  updateData: (value: any) => void;
};

type UseTableContextWithoutCell<TData> = UseTableContextBase<TData>;

export function useTableContext<TData>(cell: Cell<TData, unknown>): UseTableContextWithCell<TData>;

export function useTableContext<TData>(cell?: undefined): UseTableContextWithoutCell<TData>;

export function useTableContext<TData>(cell?: Cell<TData, unknown>) {
  const { handleSaveData, ...rest } = useContext(EditableTableContext) as TableContextType<TData>;

  function updateData(value: any) {
    if (cell) {
      const accessorKey = (cell.column.columnDef as EditableTableColumnDef<TData>).accessorKey;
      const groupId = (cell.row.original as TDataWithGroupId<TData>)?.editableTableGroupId;

      handleSaveData({
        accessorKey,
        columnId: cell.column.id,
        rowId: rest.idSelector(cell.row.original),
        value,
        ...(groupId ? { groupId } : {}),
      });

      rest.table.options.meta?.updateData(cell.row.id, accessorKey, value);
    }
  }

  return {
    ...(cell ? { updateData } : {}),
    ...rest,
  };
}
