<script setup lang="ts">
import type { FormInstance } from 'element-plus';

import type {
  ActionButton,
  CardPrimaryAction,
} from '#/components/page/CardList.vue';
import type { OfflineImpactCheck } from '#/views/ai/shared/offline-impact';

import { computed, onMounted, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';

import { useAccess } from '@easyflow/access';
import { EasyFlowFormModal } from '@easyflow/common-ui';
import { $t } from '@easyflow/locales';
import { useUserStore } from '@easyflow/stores';

import {
  Check,
  Delete,
  Edit,
  Lock,
  OfficeBuilding,
  Plus,
  Promotion,
  Search,
  Share,
} from '@element-plus/icons-vue';
import {
  ElForm,
  ElFormItem,
  ElIcon,
  ElInput,
  ElInputNumber,
  ElMessage,
  ElMessageBox,
  ElPopover,
} from 'element-plus';
import { tryit } from 'radash';

import { api } from '#/api/request';
import defaultIcon from '#/assets/ai/knowledge/book.svg';
import HeaderSearch from '#/components/headerSearch/HeaderSearch.vue';
import CardPage from '#/components/page/CardList.vue';
import PageData from '#/components/page/PageData.vue';
import PageSide from '#/components/page/PageSide.vue';
import {
  buildListRouteFullPath,
  mergeListRouteStateQuery,
  parseListRouteState,
  watchListRouteState,
} from '#/composables/useListRouteState';
import { withListReturnTo } from '#/router/list-return-context';
import { copyTextWithFeedback } from '#/utils/clipboard-feedback';
import { createLazyComponentController } from '#/utils/lazy-component';
import { buildAbsoluteAppRouteUrl } from '#/utils/share-route-context';
import { documentCollectionListRouteSchema } from '#/views/ai/documentCollection/document-collection-list-route-state';
import AiResourceCornerMeta from '#/views/ai/shared/AiResourceCornerMeta.vue';
import { confirmPublishSubmission } from '#/views/ai/shared/approval-application-reason';
import { buildOfflineImpactMessage } from '#/views/ai/shared/offline-impact';
import {
  canAiResourceDelete,
  canAiResourceOffline,
  canAiResourcePublish,
  canAiResourceRepublish,
  isAiResourceApprovalPending,
  resolveAiResourceDisplayStatus,
} from '#/views/ai/shared/publish-status';

const route = useRoute();
const router = useRouter();
const initialListState = parseListRouteState(
  route.query,
  documentCollectionListRouteSchema,
);
const selectedCategoryId = ref(initialListState.categoryId);
const searchKeyword = ref(initialListState.keyword);
const currentPageNumber = ref(initialListState.pageNumber);
const currentPageSize = ref(initialListState.pageSize);
let initialCategoryChangePending = Boolean(initialListState.categoryId);
watchListRouteState(route, documentCollectionListRouteSchema, (state) => {
  if (state.categoryId !== selectedCategoryId.value) {
    initialCategoryChangePending = Boolean(state.categoryId);
  }
  selectedCategoryId.value = state.categoryId;
  searchKeyword.value = state.keyword;
  currentPageNumber.value = state.pageNumber;
  currentPageSize.value = state.pageSize;
  pageDataRef.value?.restoreState?.({
    pageNumber: state.pageNumber,
    pageSize: state.pageSize,
    queryParams: {
      categoryId: state.categoryId || undefined,
      keyword: state.keyword || undefined,
    },
  });
});
const userStore = useUserStore();
const { hasAccessByCodes } = useAccess();
const collectionTypeLabelMap = {
  DOCUMENT: $t('documentCollection.collectionTypeDocument'),
  FAQ: $t('documentCollection.collectionTypeFaq'),
};
type VisibilityScope = 'DEPT' | 'PRIVATE' | 'PUBLIC';

interface DocumentCollectionModalInstance {
  openDialog: (row: Record<string, unknown>) => void;
}

const {
  component: DocumentCollectionModalComponent,
  componentRef: aiKnowledgeModalRef,
  ensureInstance: ensureDocumentCollectionModal,
  loading: knowledgeModalLoading,
} = createLazyComponentController<DocumentCollectionModalInstance>(
  () => import('#/views/ai/documentCollection/DocumentCollectionModal.vue'),
);

async function openKnowledgeModal(row: Record<string, unknown>) {
  try {
    const modal = await ensureDocumentCollectionModal();
    modal.openDialog(row);
  } catch (error) {
    console.error('Failed to load knowledge modal:', error);
    ElMessage.error($t('message.getDataError'));
  }
}

const canManageKnowledgePermission = computed(() =>
  hasAccessByCodes(['/api/v1/documentCollection/save']),
);
const sharingKnowledgeId = ref<null | number | string>(null);
const updatingScopeId = ref<null | number | string>(null);
const visibilityScopePopoverRefs = ref<Record<string, any>>({});
const visibilityScopeMeta = computed(() => ({
  PRIVATE: {
    label: $t('documentCollection.visibilityScopePrivate'),
    description: $t('documentCollection.visibilityScopePrivateDesc'),
    icon: Lock,
    tone: 'private',
  },
  DEPT: {
    label: $t('documentCollection.visibilityScopeDept'),
    description: $t('documentCollection.visibilityScopeDeptDesc'),
    icon: OfficeBuilding,
    tone: 'dept',
  },
  PUBLIC: {
    label: $t('documentCollection.visibilityScopePublic'),
    description: $t('documentCollection.visibilityScopePublicDesc'),
    icon: Promotion,
    tone: 'public',
  },
}));
const visibilityScopeOptions = computed(() =>
  (['PRIVATE', 'DEPT', 'PUBLIC'] as VisibilityScope[]).map((value) => ({
    value,
    ...visibilityScopeMeta.value[value],
  })),
);

function isSuperAdmin() {
  return (
    String(userStore.userInfo?.id || '') === '1' ||
    (userStore.userRoles || []).includes('super_admin')
  );
}

function canManageKnowledgeItem(row: Record<string, any>) {
  if (!canManageKnowledgePermission.value) {
    return false;
  }
  const currentUserId = String(userStore.userInfo?.id || '');
  return isSuperAdmin() || currentUserId === String(row?.createdBy || '');
}

function ensureManageKnowledgeItem(row: Record<string, any>) {
  if (canManageKnowledgeItem(row)) {
    return true;
  }
  ElMessage.warning($t('documentCollection.managePermissionHint'));
  return false;
}

function resolveNavTitle(row: Record<string, any>) {
  return row?.title || row?.name || '';
}

function currentListFullPath() {
  return buildListRouteFullPath(
    router,
    route.query,
    {
      categoryId: selectedCategoryId.value,
      keyword: searchKeyword.value,
      pageNumber: currentPageNumber.value,
      pageSize: currentPageSize.value,
    },
    documentCollectionListRouteSchema,
  );
}

function openKnowledgeDetail(row: {
  id: string;
  name?: string;
  title?: string;
}) {
  router.push({
    path: '/ai/documentCollection/document',
    query: {
      id: row.id,
      pageKey: '/ai/documentCollection',
      navTitle: resolveNavTitle(row),
      ...withListReturnTo(currentListFullPath()),
    },
  });
}

async function shareKnowledge(row: Record<string, any>) {
  if (!row?.id || sharingKnowledgeId.value === row.id) {
    return;
  }
  sharingKnowledgeId.value = row.id;
  try {
    const res = await api.post('/api/v1/knowledgeShare/url/create', {
      knowledgeId: row.id,
    });
    const shareKey = String(res.data?.shareKey || '').trim();
    if (res.errorCode !== 0 || !shareKey) {
      return;
    }
    const shareUrl = buildAbsoluteAppRouteUrl(
      router.resolve({
        name: 'KnowledgeShare',
        query: { shareKey },
      }).href,
    );
    await copyTextWithFeedback(
      shareUrl,
      $t('message.copySuccess'),
      $t('message.copyFail'),
    );
  } finally {
    sharingKnowledgeId.value = null;
  }
}

interface FieldDefinition {
  // 字段名称
  prop: string;
  // 字段标签
  label: string;
  // 字段类型：input, number, select, radio, checkbox, switch, date, datetime
  type?: 'input' | 'number';
  // 是否必填
  required?: boolean;
  // 占位符
  placeholder?: string;
}
const primaryAction: CardPrimaryAction = {
  showIndicator: false,
  text: $t('documentCollection.actions.knowledge'),
  permission: '/api/v1/documentCollection/query',
  onClick(row) {
    openKnowledgeDetail(row);
  },
};

const actions: ActionButton[] = [
  {
    icon: Edit,
    text: $t('button.edit'),
    permission: '/api/v1/documentCollection/save',
    placement: 'inline',
    onClick(row) {
      if (!ensureManageKnowledgeItem(row)) {
        return;
      }
      void openKnowledgeModal(row);
    },
  },
  {
    icon: Search,
    text: $t('documentCollection.actions.retrieve'),
    placement: 'inline',
    onClick(row) {
      router.push({
        path: '/ai/documentCollection/document',
        query: {
          id: row.id,
          pageKey: '/ai/documentCollection',
          navTitle: resolveNavTitle(row),
          activeMenu: 'knowledgeSearch',
          ...withListReturnTo(currentListFullPath()),
        },
      });
    },
  },
  {
    icon: Promotion,
    text: (row) =>
      canAiResourceRepublish(row.displayPublishStatus, row.publishStatus)
        ? $t('button.republish')
        : $t('button.publish'),
    permission: '/api/v1/documentCollection/save',
    placement: 'inline',
    visible: (row) =>
      canAiResourcePublish(row.displayPublishStatus, row.publishStatus) ||
      canAiResourceRepublish(row.displayPublishStatus, row.publishStatus),
    onClick(row) {
      if (!ensureManageKnowledgeItem(row)) {
        return;
      }
      submitPublishAction(row);
    },
  },
  {
    icon: Share,
    text: $t('button.share'),
    permission: '/api/v1/documentCollection/save',
    placement: 'menu',
    disabled: (row) => sharingKnowledgeId.value === row.id,
    loading: (row) => sharingKnowledgeId.value === row.id,
    onClick(row) {
      if (!ensureManageKnowledgeItem(row)) {
        return;
      }
      shareKnowledge(row);
    },
  },
  {
    icon: Promotion,
    text: $t('button.offline'),
    permission: '/api/v1/documentCollection/save',
    placement: 'menu',
    visible: (row) =>
      canAiResourceOffline(row.displayPublishStatus, row.publishStatus),
    onClick(row) {
      if (!ensureManageKnowledgeItem(row)) {
        return;
      }
      submitOfflineAction(row);
    },
  },
  {
    text: $t('button.delete'),
    icon: Delete,
    tone: 'danger',
    permission: '/api/v1/documentCollection/remove',
    placement: 'menu',
    visible: (row) =>
      canAiResourceDelete(row.displayPublishStatus, row.publishStatus),
    onClick(row) {
      if (!ensureManageKnowledgeItem(row)) {
        return;
      }
      submitDeleteApproval(row);
    },
  },
];

onMounted(() => {
  getCategoryList();
});
function isRepublishAction(item: any) {
  return canAiResourceRepublish(item.displayPublishStatus, item.publishStatus);
}

const submitPublishAction = async (item: any) => {
  if (
    isAiResourceApprovalPending(item.displayPublishStatus, item.publishStatus)
  ) {
    ElMessage.warning($t('documentCollection.publishPendingHint'));
    return;
  }
  const confirmation = await confirmPublishSubmission({
    api,
    confirmMessage: isRepublishAction(item)
      ? $t('documentCollection.submitRepublishApprovalConfirm')
      : $t('documentCollection.submitPublishApprovalConfirm'),
    id: item.id,
    resourcePath: '/api/v1/documentCollection',
    title: $t('message.noticeTitle'),
  });
  if (!confirmation) {
    return;
  }
  const res = await api.post(
    '/api/v1/documentCollection/submitPublishApproval',
    {
      applicationReason: confirmation.applicationReason,
      id: item.id,
    },
  );
  if (res.errorCode === 0) {
    ElMessage.success(res.message || $t('message.saveOkMessage'));
    reloadKnowledgeList();
  }
};
const submitOfflineAction = async (item: any) => {
  if (
    isAiResourceApprovalPending(item.displayPublishStatus, item.publishStatus)
  ) {
    ElMessage.warning($t('documentCollection.publishPendingHint'));
    return;
  }
  const impactRes = await api.get<{
    data: OfflineImpactCheck;
    errorCode: number;
  }>('/api/v1/documentCollection/offlineImpactCheck', {
    params: { id: item.id },
  });
  if (impactRes.errorCode !== 0) {
    return;
  }
  if (impactRes.data?.hasWorkflowUsages) {
    await ElMessageBox.alert(
      buildOfflineImpactMessage(
        $t('documentCollection.offlineImpactWorkflowBlockedIntro'),
        impactRes.data.workflowUsages,
        $t('documentCollection.offlineImpactWorkflowBlockedFooter'),
      ),
      $t('message.noticeTitle'),
      {
        confirmButtonText: $t('button.confirm'),
        type: 'warning',
      },
    );
    return;
  }
  try {
    await ElMessageBox.confirm(
      impactRes.data?.hasAgentBindings
        ? buildOfflineImpactMessage(
            $t('documentCollection.offlineImpactBoundAgentsIntro'),
            impactRes.data.agentBindings,
            $t('documentCollection.offlineImpactBoundAgentsFooter'),
          )
        : $t('documentCollection.submitOfflineApprovalConfirm'),
      $t('message.noticeTitle'),
      {
        confirmButtonText: $t('button.confirm'),
        cancelButtonText: $t('button.cancel'),
        type: 'warning',
      },
    );
  } catch {
    return;
  }
  const res = await api.post(
    '/api/v1/documentCollection/submitOfflineApproval',
    {
      id: item.id,
    },
  );
  if (res.errorCode === 0) {
    ElMessage.success(res.message || $t('message.saveOkMessage'));
    reloadKnowledgeList();
  }
};
const submitDeleteApproval = async (item: any) => {
  if (
    isAiResourceApprovalPending(item.displayPublishStatus, item.publishStatus)
  ) {
    ElMessage.warning($t('documentCollection.deletePendingHint'));
    return;
  }
  try {
    await ElMessageBox.confirm(
      $t('documentCollection.submitDeleteApprovalConfirm'),
      $t('message.noticeTitle'),
      {
        confirmButtonText: $t('button.confirm'),
        cancelButtonText: $t('button.cancel'),
        type: 'warning',
      },
    );
  } catch {
    return;
  }
  const res = await api.post(
    '/api/v1/documentCollection/submitDeleteApproval',
    {
      id: item.id,
    },
  );
  if (res.errorCode === 0) {
    ElMessage.success(res.message || $t('message.saveOkMessage'));
    reloadKnowledgeList();
  }
};
function resolvePublishStatusMeta(
  displayPublishStatus?: string,
  publishStatus?: string,
) {
  switch (resolveAiResourceDisplayStatus(displayPublishStatus, publishStatus)) {
    case 'DELETE_PENDING': {
      return {
        label: $t('documentCollection.publishStatusDeletePending'),
        tone: 'danger',
      };
    }
    case 'OFFLINE': {
      return {
        label: $t('documentCollection.publishStatusOffline'),
        tone: 'draft',
      };
    }
    case 'OFFLINE_PENDING': {
      return {
        label: $t('documentCollection.publishStatusOfflinePending'),
        tone: 'pending',
      };
    }
    case 'PUBLISH_PENDING': {
      return {
        label: $t('documentCollection.publishStatusPublishPending'),
        tone: 'pending',
      };
    }
    case 'PUBLISHED': {
      return {
        label: $t('documentCollection.publishStatusPublished'),
        tone: 'published',
      };
    }
    default: {
      return {
        label: $t('documentCollection.publishStatusDraft'),
        tone: 'draft',
      };
    }
  }
}

const pageDataRef = ref();
const headerButtons = [
  {
    key: 'add',
    text: $t('documentCollection.actions.addKnowledge'),
    icon: Plus,
    type: 'primary',
    data: { action: 'add' },
    permission: '/api/v1/documentCollection/save',
  },
];
const handleButtonClick = (event: any, _item: any) => {
  switch (event.key) {
    case 'add': {
      void openKnowledgeModal({});
      break;
    }
  }
};
const fieldDefinitions = ref<FieldDefinition[]>([
  {
    prop: 'categoryName',
    label: $t('aiWorkflowCategory.categoryName'),
    type: 'input',
    required: true,
    placeholder: $t('aiWorkflowCategory.categoryName'),
  },
  {
    prop: 'sortNo',
    label: $t('aiWorkflowCategory.sortNo'),
    type: 'number',
    required: false,
    placeholder: $t('aiWorkflowCategory.sortNo'),
  },
]);
const formRules = computed(() => {
  const rules: Record<string, any[]> = {};
  fieldDefinitions.value.forEach((field) => {
    const fieldRules = [];
    if (field.required) {
      fieldRules.push({
        required: true,
        message: `${$t('message.required')}`,
        trigger: 'blur',
      });
    }
    if (fieldRules.length > 0) {
      rules[field.prop] = fieldRules;
    }
  });
  return rules;
});
const handleSearch = (params: any) => {
  searchKeyword.value = String(params || '');
  pageDataRef.value.setQuery({
    categoryId: selectedCategoryId.value || undefined,
    keyword: searchKeyword.value || undefined,
  });
};
const reloadKnowledgeList = () => {
  pageDataRef.value?.reload?.();
};
const formData = ref<any>({});
const dialogVisible = ref(false);
const formRef = ref<FormInstance>();
function showControlDialog(item: any) {
  formRef.value?.resetFields();
  formData.value = { ...item };
  dialogVisible.value = true;
}
const categoryList = ref<any[]>([]);
const getCategoryList = async () => {
  const [, res] = await tryit(api.get)(
    '/api/v1/documentCollectionCategory/visibleList',
    {
      params: { sortKey: 'sortNo', sortType: 'asc' },
    },
  );

  if (res && res.errorCode === 0) {
    categoryList.value = [
      {
        id: '',
        categoryName: $t('common.allCategories'),
      },
      ...res.data,
    ];
    if (
      selectedCategoryId.value &&
      !categoryList.value.some(
        (item) => String(item.id) === selectedCategoryId.value,
      )
    ) {
      selectedCategoryId.value = '';
      initialCategoryChangePending = false;
      pageDataRef.value?.setQuery?.({
        keyword: searchKeyword.value || undefined,
      });
    }
  }
};
function removeCategory(row: any) {
  ElMessageBox.confirm($t('message.deleteAlert'), $t('message.noticeTitle'), {
    confirmButtonText: $t('message.ok'),
    cancelButtonText: $t('message.cancel'),
    type: 'warning',
    beforeClose: (action, instance, done) => {
      if (action === 'confirm') {
        instance.confirmButtonLoading = true;
        api
          .post('/api/v1/documentCollectionCategory/remove', { id: row.id })
          .then((res) => {
            instance.confirmButtonLoading = false;
            if (res.errorCode === 0) {
              ElMessage.success(res.message);
              done();
              getCategoryList();
            }
          })
          .catch(() => {
            instance.confirmButtonLoading = false;
          });
      } else {
        done();
      }
    },
  }).catch(() => {});
}
const controlBtns = [
  {
    icon: Edit,
    label: $t('button.edit'),
    onClick(row: any) {
      showControlDialog(row);
    },
  },
  {
    type: 'danger',
    icon: Delete,
    label: $t('button.delete'),
    onClick(row: any) {
      removeCategory(row);
    },
  },
];

const footerButton = {
  icon: Plus,
  label: $t('button.add'),
  onClick() {
    showControlDialog({});
  },
};
const saveLoading = ref(false);
function resolveVisibilityScopeMeta(scope?: string) {
  return (
    visibilityScopeMeta.value[(scope || 'PRIVATE') as VisibilityScope] ||
    visibilityScopeMeta.value.PRIVATE
  );
}
function setVisibilityScopePopoverRef(id: number | string, el: any) {
  const cacheKey = String(id);
  if (el) {
    visibilityScopePopoverRefs.value[cacheKey] = el;
    return;
  }
  delete visibilityScopePopoverRefs.value[cacheKey];
}
function closeVisibilityScopePopover(id: number | string) {
  visibilityScopePopoverRefs.value[String(id)]?.hide?.();
}
async function updateVisibilityScope(
  row: any,
  visibilityScope: VisibilityScope,
) {
  if (
    !canManageKnowledgeItem(row) ||
    !row?.id ||
    updatingScopeId.value === row.id ||
    row.visibilityScope === visibilityScope
  ) {
    closeVisibilityScopePopover(row.id);
    return;
  }
  updatingScopeId.value = row.id;
  try {
    const res = await api.post('/api/v1/documentCollection/update', {
      id: row.id,
      visibilityScope,
    });
    if (res.errorCode === 0) {
      row.visibilityScope = visibilityScope;
      ElMessage.success($t('message.updateOkMessage'));
      closeVisibilityScopePopover(row.id);
    }
  } finally {
    updatingScopeId.value = null;
  }
}
function handleSubmit() {
  formRef.value?.validate((valid) => {
    if (valid) {
      saveLoading.value = true;
      const url = formData.value.id
        ? '/api/v1/documentCollectionCategory/update'
        : '/api/v1/documentCollectionCategory/save';
      api.post(url, formData.value).then((res) => {
        saveLoading.value = false;
        if (res.errorCode === 0) {
          getCategoryList();
          ElMessage.success(res.message);
          dialogVisible.value = false;
        }
      });
    }
  });
}
function changeCategory(category: any) {
  const categoryId = String(category?.id || '');
  if (initialCategoryChangePending && categoryId === selectedCategoryId.value) {
    initialCategoryChangePending = false;
    return;
  }
  initialCategoryChangePending = false;
  selectedCategoryId.value = categoryId;
  pageDataRef.value.setQuery({
    categoryId: categoryId || undefined,
    keyword: searchKeyword.value || undefined,
  });
}
function handlePageStateChange(state: {
  pageNumber: number;
  pageSize: number;
}) {
  currentPageNumber.value = state.pageNumber;
  currentPageSize.value = state.pageSize;
  const query = mergeListRouteStateQuery(
    route.query,
    {
      categoryId: selectedCategoryId.value,
      keyword: searchKeyword.value,
      pageNumber: state.pageNumber,
      pageSize: state.pageSize,
    },
    documentCollectionListRouteSchema,
  );
  const target = router.resolve({
    path: documentCollectionListRouteSchema.path,
    query,
  });
  if (target.fullPath !== route.fullPath) {
    void router.replace(target);
  }
}
</script>

<template>
  <div v-loading="knowledgeModalLoading" class="flex h-full flex-col gap-6 p-6">
    <div class="knowledge-header">
      <HeaderSearch
        :buttons="headerButtons"
        :initial-value="searchKeyword"
        @search="handleSearch"
        @button-click="handleButtonClick"
      />
    </div>
    <div class="flex max-h-[calc(100vh-191px)] flex-1 gap-6">
      <PageSide
        label-key="categoryName"
        value-key="id"
        :menus="categoryList"
        :control-btns="controlBtns"
        :footer-button="footerButton"
        :default-selected="selectedCategoryId"
        @change="changeCategory"
      />
      <div class="h-full flex-1 overflow-auto">
        <PageData
          ref="pageDataRef"
          page-url="/api/v1/documentCollection/page"
          :page-size="initialListState.pageSize"
          :page-sizes="[12, 24, 36, 48]"
          :initial-page-number="initialListState.pageNumber"
          :initial-query-params="{
            categoryId: initialListState.categoryId || undefined,
            keyword: initialListState.keyword || undefined,
          }"
          @state-change="handlePageStateChange"
        >
          <template #default="{ pageList }">
            <CardPage
              :default-icon="defaultIcon"
              title-field="title"
              icon-field="icon"
              desc-field="description"
              :data="pageList"
              :primary-action="primaryAction"
              :actions="actions"
              density="compact"
              meta-layout="compact"
              tag-field="collectionType"
              tag-placement="details"
              :tag-map="collectionTypeLabelMap"
            >
              <template #details="{ item }">
                <AiResourceCornerMeta>
                  <template #publish>
                    <div
                      class="knowledge-publish-chip"
                      :class="`knowledge-publish-chip--${resolvePublishStatusMeta(item.displayPublishStatus, item.publishStatus).tone}`"
                    >
                      <span class="knowledge-publish-chip__dot"></span>
                      <span>{{
                        resolvePublishStatusMeta(
                          item.displayPublishStatus,
                          item.publishStatus,
                        ).label
                      }}</span>
                    </div>
                  </template>
                  <template #scope>
                    <ElPopover
                      v-if="canManageKnowledgeItem(item)"
                      :ref="(el) => setVisibilityScopePopoverRef(item.id, el)"
                      trigger="click"
                      placement="bottom-end"
                      :width="208"
                      popper-class="knowledge-visibility-popover"
                    >
                      <template #reference>
                        <button
                          type="button"
                          class="knowledge-scope-chip"
                          :class="`knowledge-scope-chip--${resolveVisibilityScopeMeta(item.visibilityScope).tone}`"
                          :disabled="updatingScopeId === item.id"
                          @click.stop
                        >
                          <ElIcon class="knowledge-scope-chip__icon">
                            <component
                              :is="
                                resolveVisibilityScopeMeta(item.visibilityScope)
                                  .icon
                              "
                            />
                          </ElIcon>
                          <span class="knowledge-scope-chip__label">
                            {{
                              resolveVisibilityScopeMeta(item.visibilityScope)
                                .label
                            }}
                          </span>
                        </button>
                      </template>
                      <div class="knowledge-scope-panel" @click.stop>
                        <button
                          v-for="option in visibilityScopeOptions"
                          :key="option.value"
                          type="button"
                          class="knowledge-scope-option"
                          :class="[
                            `knowledge-scope-option--${option.tone}`,
                            {
                              'knowledge-scope-option--active':
                                item.visibilityScope === option.value,
                            },
                          ]"
                          :disabled="updatingScopeId === item.id"
                          @click.stop="
                            updateVisibilityScope(item, option.value)
                          "
                        >
                          <span class="knowledge-scope-option__leading">
                            <span class="knowledge-scope-option__icon-wrap">
                              <ElIcon class="knowledge-scope-option__icon">
                                <component :is="option.icon" />
                              </ElIcon>
                            </span>
                            <span class="knowledge-scope-option__text">
                              <span class="knowledge-scope-option__label">
                                {{ option.label }}
                              </span>
                              <span class="knowledge-scope-option__desc">
                                {{ option.description }}
                              </span>
                            </span>
                          </span>
                          <ElIcon
                            v-if="item.visibilityScope === option.value"
                            class="knowledge-scope-option__check"
                          >
                            <Check />
                          </ElIcon>
                        </button>
                      </div>
                    </ElPopover>
                    <div
                      v-else
                      class="knowledge-scope-chip knowledge-scope-chip--readonly"
                      :class="`knowledge-scope-chip--${resolveVisibilityScopeMeta(item.visibilityScope).tone}`"
                    >
                      <ElIcon class="knowledge-scope-chip__icon">
                        <component
                          :is="
                            resolveVisibilityScopeMeta(item.visibilityScope)
                              .icon
                          "
                        />
                      </ElIcon>
                      <span class="knowledge-scope-chip__label">
                        {{
                          resolveVisibilityScopeMeta(item.visibilityScope).label
                        }}
                      </span>
                    </div>
                  </template>
                </AiResourceCornerMeta>
              </template>
            </CardPage>
          </template>
        </PageData>
      </div>
    </div>
    <EasyFlowFormModal
      v-model:open="dialogVisible"
      :closable="!saveLoading"
      :title="formData.id ? `${$t('button.edit')}` : `${$t('button.add')}`"
      :confirm-loading="saveLoading"
      :confirm-text="$t('button.confirm')"
      :submitting="saveLoading"
      @confirm="handleSubmit"
    >
      <ElForm
        ref="formRef"
        :model="formData"
        :rules="formRules"
        label-position="top"
        class="easyflow-modal-form easyflow-modal-form--compact"
      >
        <!-- 动态生成表单项 -->
        <ElFormItem
          v-for="field in fieldDefinitions"
          :key="field.prop"
          :label="field.label"
          :prop="field.prop"
        >
          <ElInput
            v-if="!field.type || field.type === 'input'"
            v-model="formData[field.prop]"
            :placeholder="field.placeholder"
          />
          <ElInputNumber
            v-else-if="field.type === 'number'"
            v-model="formData[field.prop]"
            :placeholder="field.placeholder"
            style="width: 100%"
          />
        </ElFormItem>
      </ElForm>
    </EasyFlowFormModal>

    <!--    新增知识库模态框-->
    <component
      :is="DocumentCollectionModalComponent"
      v-if="DocumentCollectionModalComponent"
      ref="aiKnowledgeModalRef"
      @reload="reloadKnowledgeList"
    />
  </div>
</template>

<style scoped>
.knowledge-publish-chip {
  display: inline-flex;
  gap: 6px;
  align-items: center;
  justify-content: center;
  min-height: 22px;
  padding: 0 8px;
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
  border: 1px solid transparent;
  border-radius: 999px;
  box-shadow: inset 0 1px 0 hsl(var(--card) / 46%);
}

.knowledge-publish-chip__dot {
  width: 6px;
  height: 6px;
  background: currentColor;
  border-radius: 999px;
  opacity: 0.88;
}

.knowledge-publish-chip--draft {
  color: hsl(var(--muted-foreground));
  background: hsl(var(--muted) / 42%);
  border-color: hsl(var(--line-subtle));
}

.knowledge-publish-chip--pending {
  color: hsl(var(--warning));
  background: hsl(var(--warning) / 12%);
  border-color: hsl(var(--warning) / 14%);
}

.knowledge-publish-chip--published {
  color: hsl(var(--success));
  background: hsl(var(--success) / 12%);
  border-color: hsl(var(--success) / 14%);
}

.knowledge-publish-chip--danger {
  color: hsl(var(--destructive));
  background: hsl(var(--destructive) / 10%);
  border-color: hsl(var(--destructive) / 14%);
}

h1 {
  margin-bottom: 30px;
  color: #303133;
  text-align: center;
}

.knowledge-scope-chip {
  display: inline-flex;
  gap: 6px;
  align-items: center;
  justify-content: center;
  min-height: 22px;
  padding: 0 8px;
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
  color: hsl(var(--text-strong));
  background: transparent;
  border: 1px solid transparent;
  border-radius: 999px;
  transition:
    border-color 0.18s ease,
    background-color 0.18s ease,
    color 0.18s ease,
    transform 0.18s ease,
    box-shadow 0.18s ease;
}

button.knowledge-scope-chip {
  cursor: pointer;
}

button.knowledge-scope-chip:hover {
  background: hsl(var(--card) / 76%);
  box-shadow: 0 8px 16px -16px hsl(var(--foreground) / 28%);
}

button.knowledge-scope-chip:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 4px hsl(var(--primary) / 12%),
    0 10px 22px -18px hsl(var(--foreground) / 32%);
}

button.knowledge-scope-chip:disabled {
  cursor: not-allowed;
  opacity: 0.72;
}

.knowledge-scope-chip--readonly {
  cursor: default;
}

.knowledge-scope-chip__icon {
  font-size: 12px;
}

.knowledge-scope-chip__label {
  white-space: nowrap;
}

.knowledge-scope-chip--private {
  color: hsl(var(--primary));
  background: hsl(var(--primary) / 10%);
  border-color: hsl(var(--primary) / 14%);
}

.knowledge-scope-chip--dept {
  color: hsl(var(--warning));
  background: hsl(var(--warning) / 12%);
  border-color: hsl(var(--warning) / 14%);
}

.knowledge-scope-chip--public {
  color: hsl(var(--success));
  background: hsl(var(--success) / 12%);
  border-color: hsl(var(--success) / 14%);
}

.knowledge-scope-panel {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.knowledge-scope-option {
  display: flex;
  gap: 10px;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 10px 8px;
  text-align: left;
  background: transparent;
  border: none;
  border-radius: 12px;
  transition:
    background-color 0.18s ease,
    transform 0.18s ease,
    color 0.18s ease;
}

.knowledge-scope-option:hover {
  background: hsl(var(--foreground) / 4%);
}

.knowledge-scope-option:focus-visible {
  outline: none;
  box-shadow: 0 0 0 4px hsl(var(--primary) / 12%);
}

.knowledge-scope-option:disabled {
  cursor: not-allowed;
  opacity: 0.72;
}

.knowledge-scope-option__leading {
  display: flex;
  gap: 8px;
  align-items: center;
  min-width: 0;
}

.knowledge-scope-option__icon-wrap {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  background: transparent;
  border-radius: 9px;
}

.knowledge-scope-option__icon {
  font-size: 15px;
}

.knowledge-scope-option__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.knowledge-scope-option__label {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.3;
  color: hsl(var(--text-strong));
}

.knowledge-scope-option__desc {
  font-size: 12px;
  line-height: 1.4;
  color: hsl(var(--text-muted));
}

.knowledge-scope-option__check {
  font-size: 16px;
  color: hsl(var(--primary));
}

.knowledge-scope-option--private .knowledge-scope-option__icon-wrap {
  color: hsl(var(--primary));
  background: hsl(var(--primary) / 10%);
}

.knowledge-scope-option--dept .knowledge-scope-option__icon-wrap {
  color: hsl(var(--warning));
  background: hsl(var(--warning) / 12%);
}

.knowledge-scope-option--public .knowledge-scope-option__icon-wrap {
  color: hsl(var(--success));
  background: hsl(var(--success) / 12%);
}

.knowledge-scope-option--private.knowledge-scope-option--active {
  background: hsl(var(--primary) / 8%);
}

.knowledge-scope-option--dept.knowledge-scope-option--active {
  background: hsl(var(--warning) / 8%);
}

.knowledge-scope-option--public.knowledge-scope-option--active {
  background: hsl(var(--success) / 8%);
}

.knowledge-scope-option--private .knowledge-scope-option__check {
  color: hsl(var(--primary));
}

.knowledge-scope-option--dept .knowledge-scope-option__check {
  color: hsl(var(--warning));
}

.knowledge-scope-option--public .knowledge-scope-option__check {
  color: hsl(var(--success));
}

:global(.knowledge-visibility-popover.el-popover.el-popper) {
  padding: 8px;
  border-color: hsl(var(--line-subtle));
  border-radius: 16px;
  box-shadow: 0 18px 34px -28px hsl(var(--foreground) / 20%);
}
</style>
