// components/form-picker/form-picker.ts
interface Option {
  label: string;
  value: any;
  checked?: boolean;
  disabled?: boolean;
  mutex?: boolean;
};


const filtration = (selected: string[] | Set<string>, options: Option[], option?: Option): string[] => {
  const _selected = new Set(selected);
  if (option) {
    if (_selected.has(option.value)) {
      _selected.delete(option.value);
    } else {
      if (option.mutex) {
        _selected.clear();
      } else {
        for (const option of options) {
          if (option.mutex) _selected.delete(option.value);
        }
      }
      _selected.add(option.value);
    }
  }

  return [..._selected];
}

const reset = (values: Option[] | Option | string, options: Option[]) => {
  const selected = new Set<string>();
  const _values = Array.isArray(values) ? values : values ? [values] : [];
  for (const item of _values) {
    const value = typeof item === 'object' ? item?.value : item;
    if (value && options.find(item => item.value === value)) selected.add(value);
  }
  for (const option of options) {
    if (option.checked) selected.add(option.value);
  }
  return filtration(selected, options);
}

Component({
  options: {
    multipleSlots: true,
  },
  lifetimes: {
    attached() {
      console.log('attached');

    }
  },
  /**
   * 组件的属性列表
   */
  properties: {
    visible: { type: Boolean, value: false },
    title: { type: String, value: '' },
    value: { type: Array, value: [] },
    options: { type: Array, value: [] },
    optionsColumns: { type: Number, value: 1 },
    itemHeight: { type: Number, value: 64 },
    multiple: { type: Boolean, value: true },
    closeOnOverlayClick: { type: Boolean, value: true },
  },

  /**
   * 组件的初始数据
   */
  data: {
    containerHeight: 350,
    gap: 8,
    selected: [] as any[],
    replenish: {} as AnyObject,
    showReplenish: false,
    replenishValue: '',

    offset: 0,
  },
  observers: {
    'options,optionsColumns,itemHeight'(options, columns, height) {
      const rows = Math.ceil(options.length / columns);
      this.setData({ containerHeight: Math.min(rows * height + (rows - 1) * this.data.gap, 350) })
    },
    'value, options'(values: Option[] | Option | string, options: Option[]) {
      this.setData({ selected: reset(values, options) });
    }
  },
  /**
   * 组件的方法列表
   */
  methods: {
    handle(event: WechatMiniprogram.TouchEvent) {
      const index = event.currentTarget.dataset.index;
      const option = this.data.options[index];
      if (option.disabled) return;

      const handle = () => {
        if (this.data.multiple) {
          this.setData({ selected: filtration(this.data.selected, this.data.options, option) });
        } else {
          this.setData({ selected: this.data.selected.includes(option.value) ? [] : [option.value] });
        }
      }

      if (option.label === '其他') {
        if (this.data.selected.includes(option.value)) {
          handle();
          this.setData({ [`replenish.${option.value}`]: '' })
        } else {
          this.setData({ showReplenish: true, replenishValue: '' });
          this.onSubConfirm = () => {
            if (this.data.replenishValue) {
              handle();
              this.setData({ [`replenish.${option.value}`]: this.data.replenishValue })
            }
            this.onSubCancel();
          }
        }
      } else {
        handle()
      }
    },
    onConfirm() {
      const get = (option: Option) => {
        if (!option) return null;
        const replenish = this.data.replenish[option.value];
        return {
          label: replenish ? replenish : option.label,
          value: replenish ? `${option.value}:${replenish}` : option.value
        }
      };
      this.setData({ visible: false })
      this.triggerEvent('confirm', {
        selected: this.data.selected,
        options: this.data.selected
          .map(value => get(this.data.options.find(item => item.value === value)))
          .filter(Boolean),
      })
      this.triggerEvent('close', { trigger: 'confirm-btn' });
    },
    onCancel() {
      this.setData({ visible: false });
      this.triggerEvent('cancel');
      this.triggerEvent('close', { trigger: 'cancel-btn' });
    },
    onSubConfirm() { },
    onSubCancel() {
      this.setData({ showReplenish: false, offset: 0 });
    },
    onVisibleChange(event: any) {
      if (!event.detail.visible) {
        this.triggerEvent('close', { trigger: event.detail.trigger })
        setTimeout(() => {
          this.setData({
            selected: reset(this.data.value, this.data.options),
            offset: 0
          });
        }, 100)
      };
    },
    onBlur() {
      this.setData({ offset: 0 })
    },

    onKeyboardheightchange(event: any) {
      const _height = event?.detail?.height;
      if (_height !== this.data.offset) this.setData({ offset: _height });
    }
  }
})