import { addDays } from 'date-fns';
import { InputType } from '../../types';
import { FilterInput, CheckboxFilterInputOption } from '../schemas';

export function mapFilterInputToRecord(
  inputs: FilterInput[],
): Record<string, string> {
  return inputs.reduce<Record<string, string>>((acc, input) => {
    if (input.type === InputType.Text) {
      acc[input.key] = input.value || '';
    } else if (input.type === InputType.Checkbox) {
      const values: string[] = [];
      input.selected?.forEach((value) => {
        const path = value.split('.');
        let current = path.shift();
        let option = input.options?.find((o) => o.key === current);
        while (path.length > 0 && option) {
          current = path.shift();
          option = option?.values?.find((o) => o.key === current);
        }
        if (option) {
          // If the option has no value but has child options, collect all child values
          if (!option.value && option.values && option.values.length > 0) {
            const collectChildValues = (
              opt: CheckboxFilterInputOption,
            ): string[] => {
              const childValues: string[] = [];
              if (opt.value) {
                childValues.push(opt.value);
              }
              if (opt.values) {
                opt.values.forEach((child) => {
                  childValues.push(...collectChildValues(child));
                });
              }
              return childValues;
            };
            values.push(...collectChildValues(option));
          } else if (option.value) {
            values.push(option.value);
          }
        }
      });
      acc[input.key] = values.join(';');
    } else if (input.type === InputType.DateRange) {
      const start = input.start ? `"${input.start}"` : '';
      const stop = input.stop
        ? `"${addDays(new Date(input.stop), 1).toISOString()}"`
        : '';
      if (start || stop) {
        acc[input.key] = `${start}-${stop}`;
      }
    } else if (input.type === InputType.NumberRange) {
      const { min, max } = input;
      if (min && max) {
        acc[input.key] = `${min}-${max}`;
      } else if (min) {
        acc[input.key] = `${min}-`;
      } else if (max) {
        acc[input.key] = `-${max}`;
      }
    }
    return acc;
  }, {});
}
