<template>
  <el-cascader
    v-if="editable"
    ref="cascaderRef"
    v-model="selected"
    @change="onCascaderChange"
    :props="cascaderProps"
    :options="options"
    :key="optionsKey"
    class="tree-case-knowledge-select-full-width"
    :size="size"
    :show-all-levels="false"
    :placeholder="$t('通用.请选择')"
    collapse-tags
    :collapse-tags-tooltip="false"
    :max-collapse-tags="1"
  />
  <span v-else class="plain-label">
    <template v-if="displayNames.length === 1">
      <el-icon class="view" @click="previewFileFun(currentFileIds[0])">
        <View />
      </el-icon>
      <OverflowTooltip :content="displayNames[0]" max-width="120px" />
    </template>
    <template v-else-if="displayNames.length >= 2">
      <el-popover placement="bottom" trigger="hover" :width="220">
        <template #reference>
          <span class="link-text">
            {{ $t('工况库.关联N个执行规范', { count: displayNames.length }) }}
          </span>
        </template>
        <div class="template-list">
          <div v-for="(name, index) in displayNames" :key="index" class="template-item">
            <el-icon class="view" @click="previewFileFun(currentFileIds[index])">
              <View />
            </el-icon>
            <OverflowTooltip :content="name" class="item-name" />
          </div>
        </div>
      </el-popover>
    </template>
  </span>
  <FilePreview
    v-if="currentPreviewFileId"
    v-model="previewVisible"
    :fileId="currentPreviewFileId"
  />
</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';
import OverflowTooltip from '@/components/common/text/overflowTooltip.vue';
import { DIR_TYPE } from '@/utils/enum/data.ts';

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(';')
        .map((path) => path.split(','))
    : []
);
const optionsKey = ref<number>(0);
const isUserSelecting = ref(false);

const onCascaderChange = (val: any) => {
  isUserSelecting.value = true;
  const paths = Array.isArray(val) ? val : [];
  const pathStrings = paths.map((path: string[]) => path.join(','));
  emit('update:modelValue', pathStrings.join(';'));

  const names = paths.map((path: string[]) => {
    const nodes = cascaderRef.value?.getCheckedNodes() || [];
    const node = nodes.find((n: any) => n.pathValues?.join(',') === path.join(','));
    return node?.pathLabels?.[node.pathLabels.length - 1] || '';
  });
  displayNames.value = names;
  emit('update:modelName', names.join(';'));
  selected.value = paths;
  nextTick(() => {
    isUserSelecting.value = false;
  });
};

const cascaderProps: CascaderProps = {
  lazy: true,
  label: 'originalName',
  value: 'id',
  emitPath: true,
  multiple: true,
  lazyLoad: async (node: any, resolve: any) => {
    let res: any = {};
    let list: any[] = [];
    if (!node?.data?.dataType) {
      res = await dataListDirApi({
        parentDirId: node?.data.parentId || '',
        dirType: DIR_TYPE.KNOWLEDGE,
      });
      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 displayNames = ref<string[]>([]);

const fetchChildren = async (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: DIR_TYPE.KNOWLEDGE,
    });
    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 {
    throw new Error('查询知识库目录失败');
  }
  return [];
};

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

  const rootList = await fetchChildren('', undefined);
  options.value = cloneDeep(rootList);

  for (const ids of pathsArray) {
    let cursorList: any[] = 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) {
        if (!found.children) {
          const childrenRaw = await fetchChildren(String(found.id), found);
          found.children = cloneDeep(childrenRaw);
        }
        cursorList = found.children || [];
      }
    }
  }
};

const currentFileIds = computed(() => {
  const paths = selected.value;
  return paths.filter((path) => path.length > 0).map((path) => Number(path[path.length - 1]));
});
const previewVisible = ref(false);
const currentPreviewFileId = ref<number>();
const previewFileFun = (fileId: number) => {
  currentPreviewFileId.value = fileId;
  nextTick(() => {
    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) => {
    // 如果是用户正在选择，跳过重新构建，避免面板关闭
    if (isUserSelecting.value) {
      return;
    }
    const pathsArray = v
      ? String(v)
          .split(';')
          .map((path) => path.split(','))
      : [];
    selected.value = pathsArray;
    if (pathsArray.length > 0 && pathsArray[0].length > 0) {
      if (props.editable) {
        await buildOptionsFromIds(pathsArray);
        optionsKey.value = Date.now();
        await nextTick();
        selected.value = pathsArray;
      }
    }
  },
  { immediate: true }
);

watch(
  () => props.modelName,
  (v) => {
    displayNames.value = v ? String(v).split(';') : [];
  },
  { immediate: true }
);

onMounted(() => {});
</script>

<style lang="scss">
.tree-case-knowledge-select-full-width.el-cascader {
  width: 100%;
}
</style>

<style scoped lang="scss">
.plain-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  vertical-align: middle;
  line-height: 1;
  max-width: 100%;
  .view {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    cursor: pointer;
    color: var(--el-color-primary);
    flex-shrink: 0;
  }
  .link-text {
    color: var(--el-color-primary);
    cursor: pointer;
    &:hover {
      text-decoration: underline;
    }
  }
}

.template-list {
  .template-item {
    display: flex;
    align-items: center;
    padding: 4px 0;
    .item-name {
      flex: 1;
      min-width: 0;
    }
    .view {
      flex-shrink: 0;
      cursor: pointer;
      color: var(--el-color-primary);
      margin-right: 8px;
    }
  }
}
</style>
