import React, { useEffect, useState } from 'react';
import styled from 'styled-components';

import type { SearchFacet, SearchFacetCount, SearchFilterItem } from '@redocly/theme/core/types';

import { useThemeHooks } from '@redocly/theme/core/hooks';
import { Select } from '@redocly/theme/components/Select/Select';
import { CounterTag } from '@redocly/theme/components/Tags/CounterTag';

type SearchFilterFieldSelectProps = {
  className?: string;
  facet: SearchFacet;
  filter: SearchFilterItem[];
  query: string;
  selectedValues: string[];
  onChange: (value: string | string[]) => void;
};

export function SearchFilterFieldSelect({
  facet,
  filter,
  query,
  selectedValues,
  onChange,
}: SearchFilterFieldSelectProps) {
  const MAX_SELECT_OPTIONS = 20;
  const { useFacetQuery, useTranslate } = useThemeHooks();
  const { translate } = useTranslate();
  const { searchFacet, setSearchFacet, setSearchFacetQuery } = useFacetQuery(facet.field);
  const [selectOptions, setSelectOptions] = useState<any[]>([]);
  const isMultiple = facet.type === 'multi-select';

  useEffect(() => {
    setSelectOptions(getSelectOptions());
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [searchFacet, facet]);

  const onSearch = (value: string | null) => {
    if (value === null) {
      setSearchFacet(null);
      setSearchFacetQuery(null);
    } else if (typeof value === 'string') {
      setSearchFacetQuery({
        query,
        filter,
        facetQuery: value,
      });
    }
  };

  const getSelectOptions = () => {
    return searchFacet
      ? searchFacet.values.map(facetValueToSelectOption)
      : facet.values.map(facetValueToSelectOption);
  };

  const facetValueToSelectOption = (facetValue?: SearchFacetCount | string) => {
    if (!facetValue) {
      return { element: null, value: '' };
    }
    if (typeof facetValue === 'string') {
      return {
        element: (
          <FilterSelectOptionWrapper>
            <FilterSelectOptionText>{facetValue}</FilterSelectOptionText>
          </FilterSelectOptionWrapper>
        ),
        value: facetValue,
      };
    } else {
      const { value, count, isCounterVisible } = facetValue as SearchFacetCount;
      return {
        element: (
          <FilterSelectOptionWrapper>
            <FilterSelectOptionText>{value}</FilterSelectOptionText>
            {isCounterVisible && <CounterTag>{count}</CounterTag>}
          </FilterSelectOptionWrapper>
        ),
        value: value,
      };
    }
  };

  return (
    <Select
      value={
        selectedValues.length
          ? isMultiple
            ? selectedValues.map((value) => facetValueToSelectOption(value))
            : facetValueToSelectOption(selectedValues[0])
          : undefined
      }
      options={selectOptions}
      onChange={onChange}
      placeholder={`${translate(
        'search.filter.field.placeholder',
        'Search',
      )} ${facet.name.toLowerCase()}...`}
      alignment="start"
      multiple={isMultiple}
      searchable={true}
      footer={
        selectOptions.length === MAX_SELECT_OPTIONS ? (
          <FilterSelectFooter>Search to show more items...</FilterSelectFooter>
        ) : null
      }
      onSearch={onSearch}
      checkmarkIconPosition="start"
    />
  );
}

const FilterSelectOptionWrapper = styled.div`
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--search-filter-field-select-option-gap);
`;

const FilterSelectOptionText = styled.span`
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  width: 100%;
  padding: var(--search-filter-field-select-option-text-padding);
`;

const FilterSelectFooter = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--search-filter-field-select-footer-padding);
  color: var(--search-filter-field-select-footer-text-color);
`;
