import React, { useContext } from 'react';
import { Pagination, PaginationProps } from '@digigov/react-core/Pagination';
import {
  PaginationList,
  PaginationListProps,
} from '@digigov/react-core/PaginationList';
import {
  usePagination,
  usePaginationReturn,
} from '@digigov/ui/navigation/Pagination/hooks';
import {
  PaginationListItemButton,
  PaginationLabel,
  PaginationResultsPerPageSelect,
  PaginationLabelProps,
  PaginationResultsPerPageSelectProps,
} from '@digigov/ui/navigation/Pagination/Pagination';

export interface PaginationLabelAutoProps
  extends Omit<PaginationLabelProps, 'start' | 'end' | 'total'> {
  start?: number;
  end?: number;
  total?: number;
}

export interface PaginationResultsPerPageSelectAutoProps
  extends Omit<
    PaginationResultsPerPageSelectProps,
    'resultsPerPageOptions' | 'currentResultsPerPage' | 'handleOnChange'
  > {
  resultsPerPageOptions?: number[];
  currentResultsPerPage?: number;
  handleOnChange?: React.Dispatch<React.SetStateAction<number>>;
}

const PaginationContext = React.createContext<usePaginationReturn | null>(null);

export const usePaginationContext = (): usePaginationReturn => {
  const context = useContext(PaginationContext);
  if (!context) {
    throw new Error(
      'usePaginationContext must be used within an PaginationProvider'
    );
  }
  return context;
};

export const PaginationContextAuto = ({
  total,
  resultsPerPageOptions,
  previousLabel,
  nextLabel,
  children,
  ...props
}: {
  total: number;
  resultsPerPageOptions: number[];
  previousLabel?: string;
  nextLabel?: string;
  children: React.ReactNode;
}) => {
  const pagination = usePagination({
    total,
    resultsPerPageOptions,
    previousLabel,
    nextLabel,
  });

  return (
    <PaginationContext.Provider value={pagination} {...props}>
      {children}
    </PaginationContext.Provider>
  );
};

export const PaginationAuto = React.forwardRef<HTMLElement, PaginationProps>(
  function PaginationAuto({ children, ...props }, ref) {
    const context = usePaginationContext();
    if (!context) {
      throw new Error('PaginationAuto must be used within PaginationProvider');
    }
    return (
      <Pagination {...props} ref={ref}>
        {children}
      </Pagination>
    );
  }
);
export const PaginationLabelAuto = React.forwardRef<
  HTMLParagraphElement,
  PaginationLabelAutoProps
>(function PaginationLabelAuto({ ...props }, ref) {
  const context = usePaginationContext();
  if (!context) {
    throw new Error(
      'PaginationLabelAuto must be used within PaginationProvider'
    );
  }
  return (
    <PaginationLabel
      {...context.registerPaginationLabel()}
      {...props}
      ref={ref}
    ></PaginationLabel>
  );
});

export const PaginationResultsPerPageSelectAuto = React.forwardRef<
  HTMLLabelElement,
  PaginationResultsPerPageSelectAutoProps
>(function PaginationResultsPerPageSelectAuto(props, ref) {
  const context = usePaginationContext();
  if (!context) {
    throw new Error(
      'PaginationResultsPerPageSelectAuto must be used within PaginationProvider'
    );
  }
  return (
    <PaginationResultsPerPageSelect
      {...context.registerPaginationResultsPerPageSelect()}
      {...props}
      ref={ref}
    />
  );
});

export const PaginationListAuto = React.forwardRef<
  HTMLUListElement,
  PaginationListProps
>(function PaginationListAuto(props, ref) {
  const context = usePaginationContext();
  if (!context) {
    throw new Error(
      'PaginationListAuto must be used within PaginationProvider'
    );
  }
  return (
    <PaginationList {...props} ref={ref}>
      {context.items.map((item, index) => {
        return <PaginationListItemButton {...item} key={index} />;
      })}
    </PaginationList>
  );
});
