<template>
  <view :class="pickerClass" :style="pickerStyle">
    <picker-view
      :class="bem.e('picker-view')"
      :indicator-class="bem.e('indicator')"
      :mask-class="bem.e('mask')"
      :value="columnIndexes"
      :immediate-change="immediateChange"
      @change="onChange"
    >
      <picker-view-column v-for="(column, i) in renderedColumns" :key="i">
        <view v-for="(option, j) in column" :key="j" :class="bem.e('item')">
          {{ getLabelByOption(option) }}
        </view>
      </picker-view-column>
    </picker-view>
  </view>
</template>

<script lang="ts">
import { defineComponent as _defineComponent } from "vue";
import { computed, nextTick, ref, watch } from "vue";
import {
  classNames,
  stringifyStyle,
  createBem,
  nestedToMulti,
  toArray,
  arrayEqual,
  isNullish
} from "../utils";
import {
  defaultOptionKeys,
  getColumnsType,
  getIndexesByValue,
  getCascaderValidIndexes,
  getOptionsByIndexes,
  getMaySingleValueByOptions,
  getValueOrLabelByOption,
  pickerProps
} from "./common";
const __default__ = {
  options: {
    virtualHost: true,
    styleIsolation: "shared"
  }
};
export default /* @__PURE__ */ _defineComponent({
  ...__default__,
  __name: "picker",
  props: pickerProps,
  emits: ["update:model-value"],
  setup(__props, { expose: __expose, emit: __emit }) {
    __expose();
    const props = __props;
    const emit = __emit;
    const bem = createBem("picker");
    const fieldKeys = computed(() => {
      return Object.assign({}, defaultOptionKeys, props.optionKeys);
    });
    const columnsType = computed(() => {
      return getColumnsType(props.columns, fieldKeys.value);
    });
    const innerValue = ref(props.modelValue);
    const columnIndexes = ref(
      getIndexesByValue(toArray(innerValue.value), props.columns, fieldKeys.value)
    );
    watch(
      () => props.modelValue,
      () => {
        innerValue.value = props.modelValue;
        if (!isNullish(props.modelValue) && props.modelValue !== "") {
          const indexes = getIndexesByValue(
            toArray(props.modelValue),
            props.columns,
            fieldKeys.value
          );
          if (!arrayEqual(indexes, columnIndexes.value)) {
            columnIndexes.value = indexes;
          }
        }
      }
    );
    const onChange = (event) => {
      let indexes = event.detail.value;
      if (indexes.some((index) => index === Infinity)) {
        nextTick(() => {
          columnIndexes.value = isNullish(innerValue.value) || innerValue.value === "" ? columnIndexes.value.map(() => 0) : [...columnIndexes.value];
        });
        return;
      }
      if (columnsType.value === "cascader") {
        let startIndex = -1;
        const nextIndexes = [];
        for (let i = 0; i < columnIndexes.value.length; i++) {
          if (startIndex < 0 && columnIndexes.value[i] !== indexes[i]) {
            startIndex = i;
          }
          nextIndexes.push(startIndex > -1 && i > startIndex ? 0 : indexes[i]);
        }
        indexes = nextIndexes;
        {
          const validIndexes = getCascaderValidIndexes(
            indexes,
            props.columns,
            fieldKeys.value
          );
          if (!arrayEqual(indexes, validIndexes)) {
            indexes = validIndexes;
          }
        }
      }
      const selectedOptions = getOptionsByIndexes(
        indexes,
        props.columns,
        fieldKeys.value
      );
      if (!arrayEqual(indexes, columnIndexes.value)) {
        columnIndexes.value = indexes;
      }
      const nextValue = getMaySingleValueByOptions(
        selectedOptions,
        fieldKeys.value,
        props.columns
      );
      innerValue.value = nextValue;
      emit("update:model-value", nextValue, selectedOptions, indexes);
    };
    const getRenderedColumns = () => {
      switch (columnsType.value) {
        case "single":
          return [props.columns];
        case "multi":
          return props.columns;
        case "cascader":
          return nestedToMulti(
            props.columns,
            toArray(innerValue.value),
            fieldKeys.value
          );
        default:
          return [];
      }
    };
    const renderedColumns = ref(getRenderedColumns());
    watch(
      [() => props.columns, innerValue],
      ([newColumns, newValue], [oldColumns, oldValue]) => {
        if (newColumns !== oldColumns || newValue !== oldValue && columnsType.value === "cascader" && !isNullish(newValue) && newValue !== "" && (!Array.isArray(newValue) || newValue.length > 0)) {
          renderedColumns.value = getRenderedColumns();
        }
      }
    );
    const getLabelByOption = (option) => {
      return getValueOrLabelByOption(option, fieldKeys.value.label);
    };
    const pickerClass = computed(() => {
      return classNames(bem.b(), props.rootClass);
    });
    const pickerStyle = computed(() => {
      return stringifyStyle(props.rootStyle);
    });
    const __returned__ = { props, emit, bem, fieldKeys, columnsType, innerValue, columnIndexes, onChange, getRenderedColumns, renderedColumns, getLabelByOption, pickerClass, pickerStyle };
    return __returned__;
  }
});
</script>

<style lang="scss">
@use './index.scss';
</style>