import { PropsWithChildren, ReactNode, createContext, useContext, useState } from 'react';

export interface HeaderMeta {
  title: ReactNode;
  sortable: boolean;
  alwaysVisible: boolean;
}

export type HeadersMeta<C extends string = string> = Record<C, HeaderMeta>;
type RegisterHeaders<C extends string = string> = (meta: HeadersMeta<C>) => void;

const HeadersContext = createContext<HeadersMeta | undefined>(undefined);
const RegisterHeadersContext = createContext<RegisterHeaders | undefined>(undefined);

/** Store metadata of HeaderCell collected by {@link useTableHeaderCellsMetaRegister}  */
export function TableHeaderCellsMetaContextProvider(props: PropsWithChildren) {
  const [headers, setHeaders] = useState<HeadersMeta>({});
  return (
    <RegisterHeadersContext.Provider value={setHeaders}>
      <HeadersContext.Provider value={headers}>{props.children}</HeadersContext.Provider>
    </RegisterHeadersContext.Provider>
  );
}

/** Returns metadata of HeaderCell components collected by {@link useTableHeaderCellsMetaRegister} */
export function useTableHeaderCellsMeta<C extends string>(): HeadersMeta<C> {
  const context = useContext(HeadersContext) as HeadersMeta<C>;
  if (!context) {
    throw new Error('useTableHeaderCellsMeta should be used only inside TableHeaderCellsMetaContextProvider');
  }
  return context;
}

export function useTableHeaderCellsRegister() {
  const context = useContext(RegisterHeadersContext);
  if (!context) {
    throw new Error(
      'useTableHeaderCellRegister should be used only inside TableHeaderCellsMetaContextProvider',
    );
  }
  return context;
}
