import { observer } from 'mobx-react';
import React from 'react';
import { View } from '../components/View';
import { Button } from '../components/Button';
import { CSSProperties, css } from 'glamor';
import { useLocalStyles } from '../styles/defaults/useLocalStyles';
import { ApphouseComponent } from './component.interfaces';
import { LayoutStyles } from '../styles/defaults/themes.interface';

/**
 * Styles for the Pagination component.
 */
export interface PaginationStyles {
  container?: CSSProperties;
  prevButton?: CSSProperties;
  nextButton?: CSSProperties;
  stepButton?: CSSProperties;
  prevButtonWrapper?: CSSProperties;
  nextButtonWrapper?: CSSProperties;
  ul?: CSSProperties;
  li?: CSSProperties;
}

/**
 * Props for the Pagination component.
 */
export interface PaginationProps extends ApphouseComponent<PaginationStyles> {
  /**
   * The current page number.
   */
  currentPage: number;
  /**
   * The total number of pages.
   */
  totalPages: number;
  /**
   * The orientation of the pagination component.
   * @default "horizontal"
   * @optional
   */
  orientation?: keyof LayoutStyles;
  /**
   * Callback function invoked when a page is changed.
   *
   * @param pageNumber - The selected page number.
   */
  onPageChange: (pageNumber: number) => void;
  /**
   * If true, the previous and next buttons will be shown.
   * @default false
   * @optional
   */
  showPrevNext?: boolean;
  /**
   * If true, the next button will be disabled.
   * if showPrevNext is false, this prop will block next buttons to be clicked
   * @default false
   */
  disableNext?: boolean;
  /**
   * If true, the page numbers will be hidden.
   * Ensure to set showPrevNext to true.
   * @default false
   */
  hideNumbers?: boolean;
  /**
   * if true, the pagination will be hidden when there is only one page
   * @default false
   */
  hideWhenOnePage?: boolean;
}

/**
 * Pagination component for navigating between pages.
 *
 * @usage
 * ```tsx
 * npm install apphouse
 * ```
 *
 * ```tsx
 * import { Pagination } from 'apphouse';
 * ```
 * ```tsx
 * <Pagination
 *   currentPage={1}
 *   totalPages={10}
 *   onPageChange={(pageNumber) => {
 *      console.log(pageNumber);
 *   }}
 *   orientation={'horizontal'}
 * />
 * ```
 */
export const Pagination: React.FC<PaginationProps> = observer(
  ({
    currentPage,
    totalPages,
    onPageChange,
    showPrevNext = false,
    styleOverwrites,
    orientation = 'horizontal',
    disableNext = false,
    hideNumbers = false,
    hideWhenOnePage = false
  }) => {
    const pageNumbers: number[] = [];

    for (let i = 1; i <= totalPages; i++) {
      pageNumbers.push(i);
    }

    if (hideWhenOnePage && totalPages === 1) {
      return null;
    }

    const componentStyles: PaginationStyles = {
      container: {
        width: '100%',
        justifyContent: 'center'
      },
      ul: {
        margin: 0,
        padding: 0,
        display: 'flex',
        flexDirection: orientation === 'horizontal' ? 'row' : 'column',
        listStyleType: 'none'
      },
      li: {}
    };

    const localStyles = useLocalStyles<PaginationStyles>(
      componentStyles,
      styleOverwrites
    );

    const showPrev = showPrevNext && currentPage > 1;
    const showNext = showPrevNext && currentPage < totalPages;
    const containerButtonsWidth = '50px';
    return (
      <View
        orientation={orientation}
        justifyContent="space-between"
        data-xray="Pagination"
        styleOverwrites={localStyles.container}
      >
        {showPrevNext && (
          <div
            {...css(
              { width: containerButtonsWidth },
              localStyles.prevButtonWrapper
            )}
            data-style="prevButtonWrapper"
          >
            {showPrev && (
              <Button
                variant={'clear'}
                onClick={() => onPageChange(currentPage - 1)}
                styleOverwrites={localStyles.prevButton}
              >
                Prev
              </Button>
            )}
          </div>
        )}

        {!hideNumbers && (
          <ul {...css(localStyles.ul)}>
            {pageNumbers.map((number) => {
              const active = currentPage === number;
              if (number < currentPage - 2 || number > currentPage + 2) {
                return null;
              }
              return (
                <li
                  key={`pagination-list-item-${number}`}
                  {...css(localStyles.li)}
                >
                  <Button
                    disabled={disableNext && number > currentPage}
                    variant={active ? 'primary' : 'clear'}
                    onClick={() => onPageChange(number)}
                    styleOverwrites={localStyles.stepButton}
                  >
                    {number}
                  </Button>
                </li>
              );
            })}
          </ul>
        )}
        {showPrevNext && (
          <div
            {...css(
              { width: containerButtonsWidth },
              localStyles.nextButtonWrapper
            )}
            data-style="nextButtonWrapper"
          >
            {showNext && (
              <Button
                variant={'clear'}
                disabled={currentPage === totalPages || disableNext}
                onClick={() => {
                  if (showPrevNext && currentPage < totalPages) {
                    onPageChange(currentPage + 1);
                  }
                }}
                styleOverwrites={localStyles.nextButton}
              >
                Next
              </Button>
            )}
          </div>
        )}
      </View>
    );
  }
);
