import React, { useEffect, useMemo } from 'react';
import { useWixPatternsContainer } from '@wix/bex-core/react';
import { observer } from 'mobx-react-lite';
import { FilterProps } from '../../model';
import { DateRangePicker } from '../DateRangePicker';
import { Box, Collapse, DatePickerProps, RadioGroup } from '@wix/design-system';
import {
  DateRangeFilterMode,
  DateRangeOptions,
  DateRangePredefinedPresetOptions,
  DateRangePreset,
  DateRangePresetOptions,
  DefaultDateRangePreset,
  MAP_DATE_PRESET_TO_KEY,
  RangeItem,
} from '@wix/bex-core';
import { useDateRangeFilterState } from '../../hooks';
import { usePatternsTheme } from '../../themes/PatternsThemeProvider';
import { renderPresetToolbarTag } from './renderPresetToolbarTag';

export interface DateRangeFilterProps
  extends FilterProps<RangeItem<Date>>,
    Partial<DatePickerProps> {
  /**
   * There are 3 possible modes:
   * - `ONLY_PREDEFINED`: show only predefined dates options
   * - `ONLY_CUSTOM`: show only custom date pickers
   * - `COMBINE`: default, combines both predefined and custom
   * @external
   */
  mode?: DateRangeFilterMode;
  /**
   * An optional array of 3 possible options: `'SEVEN_DAYS', 'FOURTEEN_DAYS', 'MONTH'`.
   * @default `['SEVEN_DAYS', 'FOURTEEN_DAYS', 'MONTH']`
   * @external
   */
  dateRangeOptions?: DateRangeOptions;

  /**
   * If to include time resolution
   * @external
   */
  filterByTime?: boolean;
}

function _DateRangeFilter(props: DateRangeFilterProps) {
  const {
    filter,
    filterByTime,
    mode = 'COMBINE',
    dateRangeOptions,
    ...rest
  } = props;

  const { translate: t } = useWixPatternsContainer();
  const {
    radioGroup: { spacing },
  } = usePatternsTheme();
  const state = useDateRangeFilterState({
    filter,
    filterByTime,
    mode,
  });

  const dateRangePreset: Partial<Record<DateRangePresetOptions, string>> =
    useMemo(() => {
      if (!dateRangeOptions) {
        return DefaultDateRangePreset;
      }
      const dateRangePresetArr = Object.keys(DateRangePreset).filter((key) =>
        dateRangeOptions.includes(key as DateRangePredefinedPresetOptions),
      );
      dateRangePresetArr.unshift(DateRangePreset.NONE);
      if (mode === 'COMBINE') {
        dateRangePresetArr.push(DateRangePreset.CUSTOM);
      }
      const dateRangePresetObjects = dateRangePresetArr.reduce(
        (cur, key) => ({
          ...cur,
          [key]: DateRangePreset[key as DateRangePresetOptions],
        }),
        {},
      ) as Record<DateRangePresetOptions, string>;

      return dateRangePresetObjects;
    }, [mode, dateRangeOptions]);

  useEffect(() => state.init(), []);

  const customElement = (
    <DateRangePicker
      dataHook="date-range-picker"
      state={state.dateRangePicker}
      {...rest}
    />
  );
  const innerComponent =
    mode === 'ONLY_CUSTOM' ? (
      customElement
    ) : (
      <Box direction="vertical">
        <RadioGroup
          value={state.dateRangePicker.selectedPreset}
          onChange={(v) =>
            v && state.dateRangePicker.onPresetChanged(v.toString())
          }
          spacing={spacing}
          dataHook="date-range-filter-group"
        >
          {Object.values(dateRangePreset).map((preset) =>
            preset === dateRangePreset.CUSTOM ? null : (
              <RadioGroup.Radio
                key={preset}
                value={preset}
                dataHook={`date-range-filter-option-${preset}`}
              >
                {t(MAP_DATE_PRESET_TO_KEY[preset])}
              </RadioGroup.Radio>
            ),
          )}
          {mode === 'COMBINE' && dateRangePreset.CUSTOM && (
            <RadioGroup.Radio
              value={dateRangePreset.CUSTOM}
              dataHook={`date-range-filter-option-${dateRangePreset.CUSTOM}`}
            >
              {t(MAP_DATE_PRESET_TO_KEY[dateRangePreset.CUSTOM])}
            </RadioGroup.Radio>
          )}
        </RadioGroup>
        <Collapse
          open={state.dateRangePicker.selectedPreset === dateRangePreset.CUSTOM}
        >
          <Box marginTop="14px" overflowY="visible">
            {customElement}
          </Box>
        </Collapse>
      </Box>
    );

  return (
    <Box dataHook={`date-range-filter-${filter.name}`} direction="vertical">
      {innerComponent}
    </Box>
  );
}
export const DateRangeFilter = observer(
  _DateRangeFilter,
) as typeof _DateRangeFilter & {
  displayName?: string;
  renderPresetToolbarTag?: typeof renderPresetToolbarTag;
};

DateRangeFilter.displayName = 'DateRangeFilter';
DateRangeFilter.renderPresetToolbarTag = renderPresetToolbarTag;
