import * as React from 'react';

import { Column } from '@tanstack/react-table';

import { Button } from '../button';

import { Chip } from '../chip';
import { CheckIcon, ChevronDownIcon, ChevronUpIcon, CloseIcon } from '@trail-ui/icons';
import { commonColors } from '@trail-ui/theme';

interface DataTableFacetedFilterProps<TData, TValue> {
  column?: Column<TData, TValue>;
  title?: string;
  options: {
    label: string;
    value: string;
    icon?: React.ComponentType<{ className?: string }>;
  }[];
  selectedFilterValues: Set<unknown>;
  setSelectedFilterValues: (values: [] | Set<unknown>) => void;
  openFilter: boolean;
}

export function TanstackTableFacetedFilter<TData, TValue>({
  column,
  title,
  options,
  selectedFilterValues,
  setSelectedFilterValues,
  // openFilter,
}: DataTableFacetedFilterProps<TData, TValue>) {
  const facets = column?.getFacetedUniqueValues();
  const selectedValues = new Set(column?.getFilterValue() as string[]);

  const [openFilterOptions, setOpenFilterOptions] = React.useState(false);

  const filterOptionsToShow = 5;
  const [loadMore, setLoadMore] = React.useState(filterOptionsToShow);
  const optionsRef = React.useRef<(HTMLButtonElement | null)[]>([]);
  const [focusedIndex, setFocusedIndex] = React.useState<number | null>(null);

  function handleLoadMore() {
    const prevLoadMore = loadMore;
    setLoadMore((prev) => prev + filterOptionsToShow);
    setTimeout(() => {
      if (optionsRef.current[prevLoadMore]) {
        optionsRef.current[prevLoadMore]?.focus();
      }
    }, 0);
  }

  React.useEffect(() => {
    if (focusedIndex !== null && optionsRef.current[focusedIndex]) {
      optionsRef.current[focusedIndex]?.focus();
    }
  }, [focusedIndex, loadMore]);

  function handleKeyDown(event: React.KeyboardEvent<HTMLButtonElement>, index: number) {
    if (event.key === 'ArrowDown') {
      setFocusedIndex((prev) => (prev !== null && prev < loadMore - 1 ? prev + 1 : 0));
    } else if (event.key === 'ArrowUp') {
      setFocusedIndex((prev) => (prev !== null && prev > 0 ? prev - 1 : loadMore - 1));
    } else if (event.key === 'Enter' || event.key === ' ') {
      event.preventDefault();
      optionsRef.current[index]?.click();
    }
  }

  return (
    <div className="relative flex flex-col items-center after:absolute after:bottom-0 after:left-3 after:block after:h-[1px] after:w-full after:bg-neutral-200 last:after:bg-neutral-50">
      <div className="w-full bg-neutral-50 p-0">
        <div className="flex items-center justify-between px-4 py-[10px]">
          <Button
            aria-expanded={openFilterOptions ? true : false}
            id={`filter-${title}`}
            aria-controls={`sect-${title}`}
            onPress={() => setOpenFilterOptions(!openFilterOptions)}
            className="flex flex-1 justify-between px-0"
            appearance="transparent"
          >
            <div className="flex items-center gap-1">
              <p className="text-sm font-semibold text-neutral-700">{title}</p>
              <p className="text-sm font-normal text-neutral-700">
                ({selectedValues.size} selected)
              </p>
            </div>
            {openFilterOptions ? (
              <ChevronUpIcon width={24} height={24} color={commonColors.neutral[800]} />
            ) : (
              <ChevronDownIcon width={24} height={24} color={commonColors.neutral[800]} />
            )}
          </Button>
        </div>
        <ul
          id={`sect-${title}`}
          aria-labelledby={`filter-${title}`}
          // onKeyDown={(event) => {
          //   if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
          //     event.preventDefault();
          //     setFocusedIndex(0);
          //   }
          // }}
          className={`${openFilterOptions ? 'h-auto max-h-60 overflow-auto' : 'h-0 max-h-0 overflow-hidden'} flex flex-col transition-all`}
        >
          {options?.slice(0, loadMore)?.map((option, index) => {
            const isSelected = selectedFilterValues.has(option.value);
            const statusStyles = {
              completed: {
                bgColor: 'bg-green-50',
                borderColor: 'border border-green-950',
              },
              regression: {
                bgColor: 'bg-red-50',
                borderColor: 'border-red-950',
              },
              inProgress: {
                bgColor: 'bg-yellow-50',
                borderColor: 'border-yellow-950',
              },
            };
            const { completed } = statusStyles;

            return (
              <li key={option.label} className="h-full last:mb-2">
                <button
                  ref={(el) => (optionsRef.current[index] = el)}
                  tabIndex={openFilterOptions ? 0 : -1}
                  onKeyDown={(event) => handleKeyDown(event, index)}
                  // appearance="transparent"
                  className={` ${isSelected && 'border-l-[3px] !border-l-purple-600 bg-purple-50 font-semibold'} flex h-10 w-full items-center justify-between rounded-none border-l-[3px] border-l-transparent px-4 text-left text-sm text-neutral-900 transition-all hover:border-l-purple-600 hover:bg-purple-50 focus:border-purple-600`}
                  onClick={() => {
                    const updatedSelectedValues = new Set(selectedFilterValues);
                    if (isSelected) {
                      updatedSelectedValues.delete(option.value);
                    } else {
                      updatedSelectedValues.add(option.value);
                    }
                    setSelectedFilterValues(updatedSelectedValues);
                  }}
                  // endContent={
                  //   isSelected ? (
                  //     <CheckIcon width={24} height={24} color={commonColors.purple[600]} />
                  //   ) : (
                  //     ''
                  //   )
                  // }
                >
                  {option.icon && <option.icon className="text-muted-foreground mr-2 h-4 w-4" />}
                  {column?.id === 'status' ? (
                    <Chip
                      tabIndex={0}
                      classNames={{
                        base: `${option.value === 'Completed' ? completed.bgColor + ' ' + completed.borderColor : option.value === 'In Progress' ? 'border border-yellow-950 bg-yellow-50' : option.value === 'Regression' ? 'border border-red-950 bg-red-50' : ''} ${!isSelected && '!border-0'} pointer-events-none`,
                      }}
                      color="default"
                      endContent={isSelected ? <CloseIcon width={16} height={16} /> : ''}
                    >
                      {option.label}
                    </Chip>
                  ) : (
                    <span className="w-full text-left">{option.label}</span>
                  )}

                  {facets?.get(option.value) && (
                    <span className="ml-auto flex h-4 w-4 items-center justify-center font-mono text-xs">
                      {facets.get(option.value)}
                    </span>
                  )}
                  {isSelected ? (
                    <CheckIcon width={24} height={24} color={commonColors.purple[600]} />
                  ) : (
                    ''
                  )}
                </button>
              </li>
            );
          })}
          <li className="flex justify-center pb-2">
            {loadMore < options.length && (
              <button
                tabIndex={openFilterOptions ? 0 : -1}
                // appearance="transparent"
                className="text-sm font-medium text-purple-600"
                onClick={handleLoadMore}
                // onKeyDown={handleKeyDown}
              >
                View More
              </button>
            )}
          </li>
        </ul>

        {/* {selectedValues.size > 0 && (
              <>
                <ul>
                  <button
                    onClick={() => column?.setFilterValue(undefined)}
                    className="justify-center text-center"
                  >
                    Clear filters
                  </button>
                </ul>
              </>
            )} */}
      </div>
    </div>
  );
}
