<template>
  <FlexView direction="column">
    <slot />
  </FlexView>
</template>

<script setup lang="ts">
import { provide, toRef, type Ref } from 'vue';
import { useChildLinkParent } from '../composeabe/ChildItem';
import FlexView from '../layout/FlexView.vue';
import { ArrayUtils } from '@imengyu/imengyu-utils';

export interface CollapseProps {
  /**
   * 当前展开面板的 name
   */
  modelValue: (number | string)[];
  /**
   * 是否开启手风琴模式
   * @default false
   */
  accordion?: boolean;
  /**
   * 动画时长(ms)，为0时禁用动画
   * @default 300
   */
  animDuration?: number;
}
export interface CollapseInstance {
  /**
   * 展开指定面板
   * @param name 面板的 name，为空时表示所有面板
   */
  open(name?: number | string): void;
  /**
   * 关闭指定面板
   * @param name 面板的 name，为空时表示所有面板
   */
  close(name?: number | string): void;
  /**
   * 切换指定面板打开状态
   * @param name 面板的 name，为空时表示所有面板
   */
  toggle(name?: number | string): void;
}

const emit = defineEmits([ 'update:modelValue' ]);
const props = withDefaults(defineProps<CollapseProps>(), {
  animDuration: 300,
  accordion: false,
});
const childNames: (number | string)[] = [];

const {
  getPosition,
} = useChildLinkParent({
  onClean: () => {
    //ArrayUtils.clear(childNames);
  },
});

export interface CollapseContext {
  activeName: Ref<(number|string)[]>,
  animDuration: Ref<number>,
  getPosition: (name?: string|number) => number,
  itemClick: (i: number | string) => void;
  
}

provide<CollapseContext>('CollapseContext', {
  activeName: toRef(props, 'modelValue'),
  animDuration: toRef(props, 'animDuration'),
  getPosition: (name) => {
    const position = getPosition().index;
    childNames.push(name ?? position);
    return position;
  },
  itemClick: (i) => {
    if (props.modelValue.includes(i)) {
      emit('update:modelValue', props.modelValue.filter((v) => v !== i));
      return;
    }
    if (props.accordion) {
      emit('update:modelValue', [i]);
    } else {
      emit('update:modelValue', [...props.modelValue, i]);
    }
  },
});

defineExpose<CollapseInstance>({
  open: (name?: number | string) => {
    if (name) {
      emit('update:modelValue', props.accordion ? [name] : [...props.modelValue, name]);
      return;
    }
    emit('update:modelValue', childNames);
  },
  close: (name?: number | string) => {
    if (name) {
      emit('update:modelValue', props.modelValue.filter((v) => v !== name));
      return;
    }
    emit('update:modelValue', []);
  },
  toggle: (name?: number | string) => {
    if (name) {
      emit('update:modelValue', props.modelValue.includes(name) ? props.modelValue.filter((v) => v !== name) : [...props.modelValue, name]);
      return;
    }
    emit('update:modelValue', childNames.filter((v) => !props.modelValue.includes(v)));
  },
});


</script>