<template>
  <view class="nana-form-picker">
    <picker-view 
      :value="pickerSelectIndex" 
      @change="bindChange" 
      class="picker-view"
      :style="{
        width: themeContext.resolveThemeSize(pickerWidth),
        height: themeContext.resolveThemeSize(pickerHeight),
      }"
    >
      <picker-view-column v-for="(column,c) in pickerVisibleCols" :key="c">
        <view class="item" v-for="(item,k) in column" :key="k">{{item.text}}</view>
      </picker-view-column>
    </picker-view>
  </view>
</template>

<script setup lang="ts">
import { onMounted, ref, watch } from 'vue';
import { useTheme } from '../theme/ThemeDefine';

const themeContext = useTheme();

export interface CascadePickerItem {
  text: string;
  value: string|number;
  children?: CascadePickerItem[];
}

export interface CascadePickerProps {
  /**
   * 选择器列，子项在 children 下面
   */
  columns: CascadePickerItem[];
  /**
   * 选择器列数量，必须与 children 嵌套层数一致，否则无法正确显示。
   */
  columnsCount: number,
  /**
   * 选中Value
   */
  value: (number|string)[],
  /**
   * picker高度
   * @default 300
   */
  pickerHeight?: string|number,
  /**
   * picker宽度
   * @default 750
   */
  pickerWidth?: string|number,
}

const emit = defineEmits([ 'update:value', 'selectTextChange' ]);
const props = withDefaults(defineProps<CascadePickerProps>(), {
  columnsCount: 1,
  pickerHeight: 300,
  pickerWidth: 750,
});

const pickerVisibleCols = ref<CascadePickerItem[][]>([]);
const pickerSelectIndex = ref<number[]>([]);

function bindChange(e: any) {
  const val = e.detail.value as number[];
  for (let i = 0; i < props.columns.length; i++) 
    if (val[i] === undefined)
      val[i] = 0;

  pickerSelectIndex.value = val;

  const selectText : string[] = [];
  const resultValue = [] as any[];
  for (let i = 0; i <= props.columnsCount; i++) {
    if (i == 0)
      resultValue[0] = props.columns[val[0]].value;
    else {
      const prevSelectedItemIndex = val[i - 1];
      const prevSelectedItem = prevSelectedItemIndex < 0 ? undefined : pickerVisibleCols.value[i - 1]?.[prevSelectedItemIndex];
      if (i < props.columns.length) {
        const newArr = prevSelectedItem?.children ?? [];
        if (pickerVisibleCols.value[i] !== newArr!) {
          pickerVisibleCols.value[i] = newArr;
          if (val[i] > newArr.length - 1)
            val[i] = newArr.length - 1;
        }
        resultValue[i] = pickerVisibleCols.value[i][val[i]]?.value ?? null;
      }
      selectText.push(prevSelectedItem?.text ?? '');
    } 
  }

  emit('update:value', resultValue);
  emit('selectTextChange', selectText.join(' '));
}
function loadCols() {
  const selectText : string[] = [];
  for (let i = 0; i <= props.columnsCount; i++) {
    if (i == 0) {
      pickerVisibleCols.value[0] = props.columns;
    } else {
      const prevSelectedItemIndex = Math.max(0, pickerVisibleCols.value[i - 1].findIndex(p => p.value === props.value[i - 1]));
      const prevSelectedItem = pickerVisibleCols.value[i - 1]?.[prevSelectedItemIndex];
      pickerSelectIndex.value[i - 1] = prevSelectedItemIndex;
      selectText.push(prevSelectedItem?.text ?? '');
      if (i < props.columns.length) {
        pickerVisibleCols.value[i] = prevSelectedItem?.children ?? [];
      }
    } 
  }
  emit('selectTextChange', selectText.join(' '), true);
}

watch(() => props.value, (v) => {
  loadCols();
})
onMounted(() => {
  loadCols();
})

defineOptions({
  options: {
    styleIsolation: "shared",
    virtualHost: true,
  }
})
</script>

<style lang="scss">
.nana-form-picker {
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: center;

  .picker-view {
    .item {
      text-align: center;
    }
  }
}
</style>