// components/form-ruler/form-ruler.ts
type Axis = {
  value: number;
  type?: 'integer' | 'median' | 'tick';
}[]
const prefix = 't-' as const;
const createAxis = (min = 0, max = 10, precision = 0.1) => {
  // const length = precision.toString().match(/\d+(?:\.(\d*))/)?.[1]?.length ?? 0
  // 计算精度的倒数（即1除以精度），然后乘以10的幂来得到一个整数
  const scale = Math.pow(10, Math.ceil(Math.log10(1 / precision)));
  const _min = min * scale;
  const _max = Math.floor(max * scale);
  const _precision = precision * scale;

  const ticks: Axis = [];
  let current = _min;
  while (current < _max + _precision) {
    ticks.push({
      value: current / scale,
      type: Math.floor(current) % 10 ? Math.floor(current) % 5 ? 'tick' : 'median' : 'integer',
    });
    current += _precision;
  }
  return ticks;
}

Component({
  options: {
    multipleSlots: true,
  },
  properties: {
    value: { type: String, value: '' },
    min: { type: Number, value: 0 },
    max: { type: Number, value: 1 },
    precision: { type: Number, value: 0.1 },
    defaultValue: { type: Number, value: Number.NaN },
    line: { type: Array, value: [] },
  },
  observers: {
    'precision'(precision: number) {
      const scale = Math.pow(10, Math.ceil(Math.log10(1 / precision)));
      this.setData({ scale });
    },
    'min, max, precision'(...args: [number, number, number]) {
      this._updateAxis(args);
    },
    'defaultValue, min, max, precision, line'(value, min, max, precision, line) {
      const offset = precision >= 1 ? precision : 0
      if (!value || Number.isNaN(+value)) {
        if (Array.isArray(line)) {
          min = line[0]?.value ?? min;
          max = line[1]?.value ?? max;
        }
        value = Math.floor((max - min - offset) / 2 + min)
      }
      this._scrollValue(value);
    }
  },
  lifetimes: {
    attached() {
      this._updateRect();
    },
  },
  data: {
    prefix,
    initialValue: '', scale: 0,
    axis: [] as Axis,
    rect: { width: 0, height: 0, gap: 5 }
  },

  /**
   * 组件的方法列表
   */
  methods: {
    _updateAxis(params: [number, number, number]) {
      const axis = createAxis.apply(null, params);
      this.setData({ axis })
    },
    _updateRect() {
      this.createSelectorQuery()
        .select('.form-ruler')
        .boundingClientRect()
        .exec(res => {
          const rect = res[0] as WechatMiniprogram.BoundingClientRectResult;
          const width = rect.width - 2;
          const height = rect.height - 2;
          this.setData({ 'rect.width': width, 'rect.height': height, });
        })
    },
    _updateValue(index?: number) {
      const value = this.data.axis[index ?? 0]?.value
      this.setData({ value: value.toFixed(Math.log10(this.data.scale)) })
    },
    _scrollValue(value: number | string) {
      const index = this.data.axis.findIndex(item => item.value === value);
      clearTimeout((this as any).lock);
      (this as any).lock = setTimeout(() => { this.setData({ initialValue: `${prefix}${index}` }); }, 300);
    },
    onScrollUpdate(event: WechatMiniprogram.ScrollViewScroll) {
      const left = event.detail.scrollLeft;
      if (left >= 0) { this._updateValue(Math.floor(left / this.data.rect.gap)); }
    },
    onScrollEnd() {
      this._scrollValue(this.data.value);
    }
  }
})