import { memo, useCallback } from 'react';
import { type FilterCommonProps, FilterOpener } from '@assets/filters/common/components/common';
import { useConfig, useFilterData } from '@assets/filters/state';
import { useTheme } from '@assets/filters/common/contexts/theme';
import type { OrProduceWith } from '@assets/js-shop/helpers';
import { type OptRange, RangeFilter } from '@assets/filters/common/components/RangeFilter';
import { usePriceFormatter } from '@assets/js-shop/hooks';
import { translate as _ } from '@assets/js-shop/ShopUtils';
import { Histogram } from '@assets/filters/common/components/Histogram';
import { trackPriceRangeChange } from '@assets/filters/price-range/trackPriceRangeChange';

function PriceRangeFilter({ openerBehaviour = {} }: FilterCommonProps<'range'>) {
   const { priceRange: priceRangeConfig } = useConfig();
   const { filterData: { priceRange }, setFilterData } = useFilterData();
   const { range: theme } = useTheme();

   const setPriceRange = useCallback((priceRangeOrProducer: OrProduceWith<OptRange>) => {
      setFilterData(prev => {
         let newPriceRange: OptRange;
         if (typeof priceRangeOrProducer === 'function') {
            newPriceRange = priceRangeOrProducer(prev.priceRange);
         } else {
            newPriceRange = priceRangeOrProducer;
         }

         trackPriceRangeChange(
            priceRangeConfig,
            newPriceRange,
         );

         if (!newPriceRange) {
            const newState = { ...prev };
            delete newState.priceRange;

            return newState;
         }

         return {
            ...prev,
            priceRange: newPriceRange,
         };
      });
   }, [setFilterData]);

   const formatPrice = usePriceFormatter({
      locale: priceRangeConfig?.locale ?? 'cs_CZ',
      currencyCode: priceRangeConfig?.currency ?? 'CZK',
   });

   if (!priceRangeConfig || (!priceRangeConfig.from && !priceRangeConfig.to)) {
      return <></>;
   }

   return (
      <FilterOpener
         title={_('price')}
         isOpen={!!priceRange}
         {...theme.openerBehaviour}
         {...openerBehaviour}
      >
         <RangeFilter
            label={!!priceRangeConfig.histogram && (
               <Histogram buckets={priceRangeConfig.histogram} />
            )}
            config={priceRangeConfig}
            range={priceRange}
            setRange={setPriceRange}
            renderInputValue={(value) => value !== '' ? formatPrice(value) : value}
         />
      </FilterOpener>
   );
}

const MemoizedPriceRangeFilter = memo(PriceRangeFilter);
export { MemoizedPriceRangeFilter as PriceRangeFilter };
