<template>
  <el-cascader
    v-if="editable"
    ref="cascaderRef"
    v-model="selected"
    @change="onCascaderChange"
    :props="cascaderProps"
    :options="options"
    :key="optionsKey"
    class="full"
    :size="size"
    :show-all-levels="false"
    placeholder="请选择"
  />
  <span v-else class="plain-label">
    <el-icon class="view" @click="previewFileFun">
      <View />
    </el-icon>
    {{ modelName || displayValue }}
  </span>
  <FilePreview v-if="currentFileId" v-model="previewVisible" :fileId="currentFileId" />
</template>

<script setup lang="ts">
import { onMounted, ref, watch, nextTick, computed } from 'vue';
import { dataListDirApi, dataQueryDirApi } from '@/api/data/data';
import { cloneDeep } from 'lodash-es';
import type { CascaderProps } from 'element-plus';
import FilePreview from '@/components/common/filePreview/index.vue';

interface Props {
  modelValue?: any;
  modelName?: string;
  editable?: boolean;
  size?: '' | 'large' | 'default' | 'small'
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: null,
  modelName: '',
  editable: true,
  size: 'default',
});

const emit = defineEmits(['update:modelValue', 'update:modelName']);

const selected = ref<string[]>(props.modelValue ? String(props.modelValue).split(',') : []);
const optionsKey = ref<number>(0);

const onCascaderChange = (val: any) => {
  const ids = Array.isArray(val) ? val.map(String) : [];
  emit('update:modelValue', ids.join(','));
  selected.value = ids;
};

const cascaderProps: CascaderProps = {
  lazy: true,
  label: 'originalName',
  value: 'id',
  emitPath: true,
  lazyLoad: async (node: any, resolve: any) => {
    let res: any = {};
    let list: any[] = [];
    if (!node?.data?.dataType) {
      res = await dataListDirApi({
        parentDirId: node?.data.parentId || '',
      });
      if (res?.code === 200) {
        list = res.data.map((item: any) => {
          return {
            ...item,
            leaf: item.dataType === 2,
          };
        });
      }
    } else if (node?.data?.dataType === 1) {
      res = await dataQueryDirApi({
        fileId: node?.data.id,
        current: 1,
        size: 999,
      });
      if (res?.code === 200) {
        list = res.data.data.map((item: any) => {
          return {
            ...item,
            leaf: item.dataType === 2,
          };
        });
      }
    } else {
      resolve([]);
      return;
    }
    const nodes = cloneDeep(list);
    resolve(nodes);
  },
};
const cascaderRef = ref<any>('');

const options = ref<any[]>([]);
const displayValue = ref('');

async function fetchChildren(parentId: string, parentNodeData?: any) {
  try {
    if (parentNodeData && parentNodeData.dataType === 1) {
      const res: any = await dataQueryDirApi({ fileId: parentNodeData.id, current: 1, size: 999 });
      if (res?.code === 200) {
        return res.data.data.map((item: any) => ({
          ...item,
          id: String(item.id),
          originalName: item.originalName || item.name,
          leaf: item.dataType === 2,
        }));
      }
    }
    const res2: any = await dataListDirApi({ parentDirId: parentId || '', dirType: 1 });
    if (res2?.code === 200) {
      return res2.data.map((item: any) => ({
        ...item,
        id: String(item.id),
        originalName: item.originalName || item.name,
        leaf: item.dataType === 2,
      }));
    }
  } catch (e) {
    throw new Error('查询知识库目录失败', e);
  }
  return [];
}

async function buildOptionsFromIds(ids: string[]) {
  options.value = [];
  if (!ids || ids.length === 0) return;

  let cursorList: any[] = [];
  const rootList = await fetchChildren('', undefined);
  options.value = cloneDeep(rootList);
  cursorList = options.value;

  for (let i = 0; i < ids.length; i++) {
    const id = String(ids[i]);
    const found = cursorList.find((n: any) => String(n.id) === id);
    if (!found) {
      break;
    }
    if (i < ids.length - 1) {
      const childrenRaw = await fetchChildren(String(found.id), found);
      const childrenNodes = cloneDeep(childrenRaw);
      found.children = childrenNodes;
      cursorList = found.children || [];
    } else {
      break;
    }
  }
  return;
}

const currentFileId = computed(() => {
  const ids = selected.value;
  if (ids.length > 0) {
    return Number(ids[ids.length - 1]);
  }
  return null;
});
const previewVisible = ref(false);
const previewFileFun = () => {
  previewVisible.value = true;
};

// async function loadDisplayNames(ids: string[]) {
//   if (!ids || ids.length === 0) {
//     displayValue.value = '';
//     return;
//   }
//   const names: string[] = [];
//   let parentId = '';
//   for (const id of ids) {
//     let found: any = null;
//     try {
//       const res1: any = await dataListDirApi({ parentDirId: parentId || '' });
//       if (res1?.code === 200) {
//         const list1 = res1.data.map((item: any) => ({ ...item, leaf: item.dataType === 2 }));
//         found = list1.find((i: any) => String(i.id) === String(id));
//       }
//     } catch {
//       throw new Error('查询知识库目录失败');
//     }
//     if (!found) {
//       try {
//         const res2: any = await dataQueryDirApi({ fileId: parentId || '', current: 1, size: 999 });
//         if (res2?.code === 200) {
//           const list2 = res2.data.data.map((item: any) => ({ ...item, leaf: item.dataType === 2 }));
//           found = list2.find((i: any) => String(i.id) === String(id));
//         }
//       } catch {
//         throw new Error('查询知识库目录失败');
//       }
//     }
//     if (found) {
//       names.push(found.originalName || found.name || String(found.id));
//       parentId = found.id;
//     } else {
//       names.push(String(id));
//       parentId = id;
//     }
//   }
//   displayValue.value = names[names.length - 1] || '';
// }

watch(() => props.modelValue, async (v) => {
  const ids = v ? String(v).split(',') : [];
  selected.value = ids;
  if (ids.length > 0) {
    // await loadDisplayNames(ids);
    if (props.editable) {
      await buildOptionsFromIds(ids);
      optionsKey.value = Date.now();
      await nextTick();
      selected.value = ids;
    }
  } else {
    if (props.modelName) {
      displayValue.value = props.modelName;
    } else {
      // displayValue.value = '';
      displayValue.value = props.modelValue || '';
    }
  }
}, { immediate: true });

// watch(() => props.modelName, (v) => {
//   const hasIds = props.modelValue && String(props.modelValue).length > 0;
//   if (!hasIds) {
//     displayValue.value = v || '';
//   }
// }, { immediate: true });

onMounted(() => {
  // if (props.editable) {
  //   const ids = props.modelValue ? String(props.modelValue).split(',') : [];
  //   buildOptionsFromIds(ids);
  // }
});
</script>

<style scoped lang="scss">
:deep(.full) {
  width: 100%;
}
.plain-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  vertical-align: middle;
  line-height: 1;
  .view {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    cursor: pointer;
    color: var(--el-color-primary);
    margin-right: 0;
  }
}
</style>
