'use client';

import { ChangeEventHandler, ReactNode } from 'react';

import { Icon } from '@iconify/react';
import Button from '@/components/Button';

import { cn } from '@/lib/helper';

const range = (start: number, end: number) =>
  Array.from({ length: end - start + 1 }, (_, i) => i + start);

const PaginationButton = ({
  content = '',
  disabled = false,
  onClick = () => {},
}: {
  content?: ReactNode;
  disabled?: boolean;
  onClick?: () => void;
}) => (
  <Button
    variant='ghost'
    color='none'
    disabled={disabled}
    onClick={onClick}
    className={cn(
      'join-item w-10 h-10 grid place-items-center p-2.5 rounded-lg! text-sm font-semibold text-base-content/50 aspect-square',
      'disabled:text-primary disabled:pointer-events-auto! disabled:cursor-not-allowed! disabled:bg-primary/10 disabled:active:translate-y-0'
    )}
  >
    {content}
  </Button>
);

const EtcPaginationButton = ({
  startPage = 0,
  endPage = 0,
  onPageItemClick,
}: {
  startPage: number;
  endPage: number;
  onPageItemClick: (a: number) => void;
}) => {
  const pages = range(startPage, endPage);

  return (
    <>
      {startPage > 0 && endPage >= startPage && (
        <div className='dropdown dropdown-top dropdown-center'>
          <button
            tabIndex={0}
            role='button'
            className={cn(
              'join-item btn btn-ghost p-2.5 rounded-lg! text-sm font-medium text-gray-500 aspect-square'
            )}
          >
            ...
          </button>

          <div className='dropdown-content'>
            <ul
              tabIndex={0}
              className='menu bg-base-100 rounded-lg! z-1 w-fit min-w-max max-h-64 p-1 shadow-sm mb-2 overflow-y-auto flex-nowrap'
            >
              {pages.map((pageNumber) => (
                <li key={pageNumber}>
                  <PaginationButton
                    content={pageNumber}
                    onClick={() => onPageItemClick(pageNumber)}
                  />
                </li>
              ))}
            </ul>
          </div>
        </div>
      )}

      {(startPage === 0 || endPage < startPage) && (
        <button
          disabled
          className={cn(
            'join-item btn btn-ghost p-2.5 rounded-lg! text-sm font-medium text-gray-500 aspect-square'
          )}
        >
          ...
        </button>
      )}
    </>
  );
};

const Pagination = ({
  currentPage = 1,
  totalItems = 0,
  itemsPerPage = 10,
  rowOptions = [10, 20, 50, 100],
  onPageChange,
  onPrevPage = () => {},
  onNextPage = () => {},
  onRowChange,
}: {
  currentPage: number;
  totalItems: number;
  itemsPerPage: number;
  rowOptions?: number[];
  onPageChange: (pageNumber: number) => void;
  onPrevPage: () => void;
  onNextPage: () => void;
  onRowChange?: (row: number) => void;
}) => {
  const totalPages =
    Math.ceil(totalItems / itemsPerPage) === 0
      ? 1
      : Math.ceil(totalItems / itemsPerPage);

  const pageChangeHandler = (pageNumber: number) => onPageChange(pageNumber);
  const firstPageClickHandler = () => onPageChange(1);
  const lastPageClickHandler = () => onPageChange(totalPages);

  const rowChangeHandler: ChangeEventHandler<HTMLSelectElement> = (e) => {
    onRowChange?.(Number(e.target.value));
  };

  const DisplayedRowCountSelect = () => (
    <div className='flex flex-row items-center gap-4'>
      <span className='text-sm font-medium text-base-content/50'>Showing</span>

      <select
        defaultValue={itemsPerPage}
        onChange={rowChangeHandler}
        className='select select-xs w-fit pl-3 pr-7 text-base-content/50'
      >
        {rowOptions.map((rowOption, rowOptionIdx) => (
          <option
            key={rowOptionIdx}
            value={rowOption}
            className='text-base-content active:text-neutral-content'
          >
            {rowOption} Per page
          </option>
        ))}
      </select>
    </div>
  );

  const GoToFirstPageButton = () => (
    <Button
      disabled={currentPage === 1}
      onClick={firstPageClickHandler}
      variant='ghost'
      color='none'
      className={cn(
        'join-item w-10 h-10 grid place-items-center p-2.5 rounded-lg! text-sm font-semibold text-base-content/50 aspect-square',
        'disabled:bg-[initial]! disabled:text-base-content disabled:pointer-events-auto! disabled:cursor-not-allowed disabled:active:translate-y-0'
      )}
    >
      <Icon
        icon='heroicons:chevron-double-left'
        width={20}
        height={20}
        className='text-gray-400 group-disabled:text-gray-300'
      />
    </Button>
  );

  const PrevPageButton = () => (
    <Button
      disabled={currentPage === 1}
      onClick={onPrevPage}
      variant='ghost'
      color='none'
      className={cn(
        'join-item w-10 h-10 grid place-items-center p-2.5 rounded-lg! text-sm font-semibold text-base-content/50 aspect-square',
        'disabled:bg-[initial]! disabled:text-base-content disabled:pointer-events-auto! disabled:cursor-not-allowed disabled:active:translate-y-0'
      )}
    >
      <Icon
        icon='heroicons:chevron-left'
        width={20}
        height={20}
        className='text-gray-400 group-disabled:text-gray-300'
      />
    </Button>
  );

  const GoToLastPageButton = () => (
    <Button
      variant='ghost'
      color='none'
      disabled={currentPage === totalPages}
      onClick={lastPageClickHandler}
      className={cn(
        'join-item w-10 h-10 grid place-items-center p-2.5 rounded-lg! text-sm font-semibold text-base-content/50 aspect-square',
        'disabled:bg-[initial]! disabled:text-base-content disabled:pointer-events-auto! disabled:cursor-not-allowed disabled:active:translate-y-0'
      )}
    >
      <Icon
        icon='heroicons:chevron-double-right'
        width={20}
        height={20}
        className='text-gray-400 group-disabled:text-gray-300'
      />
    </Button>
  );

  const NextPageButton = () => (
    <Button
      variant='ghost'
      color='none'
      disabled={currentPage === totalPages}
      onClick={onNextPage}
      className={cn(
        'join-item w-10 h-10 grid place-items-center p-2.5 rounded-lg! text-sm font-semibold text-base-content/50 aspect-square',
        'disabled:bg-[initial]! disabled:text-base-content disabled:pointer-events-auto! disabled:cursor-not-allowed disabled:active:translate-y-0'
      )}
    >
      <Icon
        icon='heroicons:chevron-right'
        width={20}
        height={20}
        className='text-gray-400 group-disabled:text-gray-300'
      />
    </Button>
  );

  const PageInfo = () => (
    <span className='text-nowrap text-sm font-medium text-base-content/50'>
      Total Item: {totalItems} | Page {currentPage} of {totalPages}
    </span>
  );

  return (
    <div className='@container'>
      <div className='flex flex-row justify-center items-center'>
        <div className='hidden @md:block'>
          <DisplayedRowCountSelect />
        </div>

        <div className='join w-full justify-end @md:justify-center items-center gap-0.5'>
          <div className='hidden @md:block'>
            <GoToFirstPageButton />
          </div>

          <div className='hidden @md:block'>
            <PrevPageButton />
          </div>

          {totalPages <= 7 &&
            range(1, totalPages).map((pageNumber) => (
              <PaginationButton
                key={pageNumber}
                content={pageNumber}
                disabled={currentPage === pageNumber}
                onClick={() => pageChangeHandler(pageNumber)}
              />
            ))}

          {totalPages > 7 && (
            <>
              <PaginationButton
                content={1}
                disabled={currentPage === 1}
                onClick={() => pageChangeHandler(1)}
              />

              {totalPages >= 2 &&
                (currentPage <= 3 || currentPage >= totalPages - 2) && (
                  <PaginationButton
                    content={2}
                    disabled={currentPage === 2}
                    onClick={() => pageChangeHandler(2)}
                  />
                )}

              {totalPages >= 2 &&
                currentPage > 3 &&
                currentPage < totalPages - 2 && (
                  <EtcPaginationButton
                    startPage={2}
                    endPage={currentPage - 2}
                    onPageItemClick={pageChangeHandler}
                  />
                )}

              {totalPages >= 3 &&
                (currentPage <= 4 || currentPage >= totalPages - 2) &&
                currentPage !== totalPages - 2 && (
                  <PaginationButton
                    content={3}
                    disabled={currentPage === 3}
                    onClick={() => pageChangeHandler(3)}
                  />
                )}

              {totalPages >= 7 &&
                (currentPage <= 2 || currentPage >= totalPages - 2) && (
                  <EtcPaginationButton
                    startPage={
                      currentPage <= 2
                        ? currentPage + 2
                        : currentPage === totalPages - 2
                          ? 3
                          : currentPage >= totalPages - 1
                            ? 4
                            : 1
                    }
                    endPage={
                      currentPage <= 2 || currentPage >= totalPages - 1
                        ? totalPages - 3
                        : currentPage === totalPages - 2
                          ? totalPages - 4
                          : 2
                    }
                    onPageItemClick={pageChangeHandler}
                  />
                )}

              {totalPages >= 3 &&
                currentPage > 4 &&
                currentPage < totalPages - 1 && (
                  <PaginationButton
                    content={currentPage - 1}
                    onClick={() => pageChangeHandler(currentPage - 1)}
                  />
                )}

              {totalPages >= 7 &&
                currentPage > 3 &&
                currentPage < totalPages - 2 && (
                  <PaginationButton content={currentPage} disabled />
                )}

              {totalPages >= 5 &&
                currentPage > 2 &&
                currentPage < totalPages - 2 && (
                  <PaginationButton
                    content={currentPage + 1}
                    onClick={() => pageChangeHandler(currentPage + 1)}
                  />
                )}

              {totalPages >= 5 &&
                (currentPage <= 2 || currentPage >= totalPages - 2) && (
                  <PaginationButton
                    content={totalPages - 2}
                    disabled={currentPage === totalPages - 2}
                    onClick={() => pageChangeHandler(totalPages - 2)}
                  />
                )}

              {totalPages >= 6 &&
                currentPage > 2 &&
                currentPage < totalPages - 3 && (
                  <EtcPaginationButton
                    startPage={
                      currentPage <= 3
                        ? currentPage + 2
                        : currentPage >= 4
                          ? currentPage + 2
                          : 1
                    }
                    endPage={
                      currentPage <= 3
                        ? totalPages - 2
                        : currentPage >= 4
                          ? totalPages - 1
                          : 0
                    }
                    onPageItemClick={pageChangeHandler}
                  />
                )}

              {totalPages >= 6 &&
                (currentPage <= 3 || currentPage >= totalPages - 3) && (
                  <PaginationButton
                    content={totalPages - 1}
                    disabled={currentPage === totalPages - 1}
                    onClick={() => pageChangeHandler(totalPages - 1)}
                  />
                )}

              {totalPages >= 7 && (
                <PaginationButton
                  content={totalPages}
                  disabled={currentPage === totalPages}
                  onClick={() => pageChangeHandler(totalPages)}
                />
              )}
            </>
          )}

          <div className='hidden @md:block'>
            <NextPageButton />
          </div>

          <div className='hidden @md:block'>
            <GoToLastPageButton />
          </div>
        </div>

        <div className='hidden @md:block'>
          <PageInfo />
        </div>
      </div>

      <div className='flex @md:hidden flex-col justify-center items-end gap-2'>
        <div className='flex flex-row items-center gap-0.5'>
          <GoToFirstPageButton />
          <PrevPageButton />
          <NextPageButton />
          <GoToLastPageButton />
        </div>

        <div className='flex flex-row items-center gap-4'>
          <DisplayedRowCountSelect />

          <PageInfo />
        </div>
      </div>
    </div>
  );
};

export default Pagination;
