import {
   type ChangeEvent,
   type ComponentProps,
   type ReactNode,
   type Ref,
   forwardRef,
   memo,
   useCallback,
} from 'react';
import { useFilterData } from '@assets/filters/state';
import { translate as _t } from '@assets/js-shop/ShopUtils';
import { FilterOpener, type OpenerBehaviour } from '@assets/filters/common/components/common';

export type SearchFilterProps = Omit<ComponentProps<'input'>, 'value' | 'defaultValue'> & {
   openerTitle?: ReactNode;
   openerBehaviour?: OpenerBehaviour & { hidden?: boolean };
};

function SearchFilter(props: SearchFilterProps, ref: Ref<HTMLInputElement>) {
   const {
      openerBehaviour = {},
      openerTitle = _t('searchInSection'),
      ...restProps
   } = props;
   const { filterData: { search }, setFilterData } = useFilterData();

   // filter is debounced on top - no need to do it here again
   const handleSubmit = useCallback(
      (ev: ChangeEvent<HTMLInputElement>) => setFilterData(prev => {
         const value = ev.target.value;

         const newState = { ...prev, search: value };
         if (!value) {
            delete newState.search;
         }

         return newState;
      }),
      [setFilterData],
   );

   const searchInput = (
      <div className="filter-item-values">
         <div className="filter-search-input">
            <i className="c-icon" dangerouslySetInnerHTML={{ __html: require('@assets/icons/search.svg?raw') }}/>
            <input
               value={search ?? ''}
               onChange={handleSubmit}
               type="text"
               className="form-control"
               placeholder={_t('searchPlaceholder')}
               {...restProps}
               ref={ref}
            />
         </div>
      </div>
   );

   const { hidden: openerHidden, ...openerProps } = openerBehaviour;
   if (openerHidden) {
      return searchInput;
   }

   return (
      <FilterOpener title={openerTitle} isOpen={!!search} {...openerProps}>
         {searchInput}
      </FilterOpener>
   );
}

const MemoizedSearchFilter = memo(forwardRef(SearchFilter));
export { MemoizedSearchFilter as SearchFilter };
