<template>
  <div class="page ctms-page-shell page--flush" :class="{ 'document-page--desktop': isDesktop }" @click="closeDocumentContextMenu">
    <div class="main-content-flat unified-shell">
      <div class="filter-container unified-action-bar bar--flush">
        <el-form :inline="true" :model="filters" class="filter-form">
          <div class="filter-item-form">
            <el-select v-model="filters.scope_type" :placeholder="TEXT.modules.fileVersionManagement.filters.scope" clearable class="filter-select-comp">
              <el-option v-for="item in scopeOptions" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </div>
          <div class="filter-item-form">
            <el-select v-model="filters.site_id" :placeholder="TEXT.modules.fileVersionManagement.filters.site" clearable filterable class="filter-select-comp">
              <el-option v-for="item in siteOptions" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </div>
          <div class="filter-item-form">
            <el-select v-model="filters.doc_type" :placeholder="TEXT.modules.fileVersionManagement.filters.docType" clearable class="filter-select-comp">
              <el-option v-for="item in docTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </div>
          <div class="filter-item-form">
            <el-button @click="resetFilters">{{ TEXT.common.actions.reset }}</el-button>
          </div>
          <div class="filter-spacer"></div>
          <el-button v-if="canCreate" type="primary" @click="openCreate" class="header-action-btn">
            <el-icon class="el-icon--left"><Plus /></el-icon>
            {{ TEXT.modules.fileVersionManagement.newDocument }}
          </el-button>
        </el-form>
      </div>
      <section class="unified-section document-table-section section--flush-x section--flush-top section--flush-bottom">
        <div class="document-workbench" :class="{ 'is-desktop': isDesktop }">
          <div class="document-table-pane" :tabindex="isDesktop ? 0 : undefined" @keydown.enter.prevent="openSelectedDocument">
            <el-table
              :data="sortedItems"
              v-loading="loading"
              @row-click="handleDocumentRowClick"
              @row-dblclick="openDocumentDetail"
              @row-contextmenu="openDocumentContextMenu"
              :row-class-name="documentRowClass"
              class="ctms-table"
              highlight-current-row
              table-layout="fixed"
            >
              <el-table-column prop="title" :label="TEXT.modules.fileVersionManagement.columns.title" show-overflow-tooltip>
                <template #default="{ row }">
                  <span class="font-semibold">{{ row.title }}</span>
                </template>
              </el-table-column>
              <el-table-column :label="TEXT.modules.fileVersionManagement.columns.scope">
                <template #default="{ row }">
                  <el-tag
                    effect="plain"
                    :type="row.scope_type === 'SITE' ? 'warning' : 'success'"
                  >
                    {{ displayEnum(TEXT.enums.scopeType, row.scope_type) }}
                  </el-tag>
                </template>
              </el-table-column>
              <el-table-column :label="TEXT.modules.fileVersionManagement.columns.site" show-overflow-tooltip>
                <template #default="{ row }">
                  <span>{{ displaySite(row.site_id) }}</span>
                </template>
              </el-table-column>
              <el-table-column :label="TEXT.modules.fileVersionManagement.columns.docType">
                <template #default="{ row }">
                  <el-tag effect="plain" type="info">{{ displayText(row.doc_type, TEXT.enums.documentType) }}</el-tag>
                </template>
              </el-table-column>
              <el-table-column :label="TEXT.modules.fileVersionManagement.columns.currentVersion">
                <template #default="{ row }">
                  <span v-if="row.current_effective_version">{{ row.current_effective_version.version_no }}</span>
                  <span v-else class="text-secondary">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="updated_at" :label="TEXT.modules.fileVersionManagement.columns.updatedAt" show-overflow-tooltip>
                <template #default="{ row }">
                  <span class="text-secondary datetime-stack">
                    <span>{{ splitDateTime(row.updated_at).date }}</span>
                    <span class="datetime-stack__time">{{ splitDateTime(row.updated_at).time }}</span>
                  </span>
                </template>
              </el-table-column>
              <el-table-column v-if="!isDesktop && (canUpdate || canDelete)" :label="TEXT.modules.fileVersionManagement.columns.actions" width="130" fixed="right">
                <template #default="{ row }">
                  <div class="cell-actions">
                    <el-button v-if="canUpdate" link type="primary" size="small" :disabled="isInactiveSite(row.site_id)" @click.stop="openEdit(row)">
                      {{ TEXT.common.actions.edit }}
                    </el-button>
                    <el-button v-if="canDelete" link type="danger" size="small" :disabled="isInactiveSite(row.site_id)" @click.stop="confirmDelete(row)">
                       {{ TEXT.common.actions.delete }}
                    </el-button>
                  </div>
                </template>
              </el-table-column>
              <template #empty>
                <el-empty :description="TEXT.modules.fileVersionManagement.emptyDescription" />
              </template>
            </el-table>
          </div>

          <aside v-if="isDesktop" class="document-preview-pane">
            <template v-if="selectedDocument">
              <div class="preview-head">
                <div>
                  <div class="preview-kicker">当前文档</div>
                  <div class="preview-title">{{ selectedDocument.title || TEXT.common.fallback }}</div>
                </div>
                <el-button size="small" type="primary" @click="openSelectedDocument">打开详情</el-button>
              </div>
              <dl class="preview-list">
                <dt>{{ TEXT.modules.fileVersionManagement.columns.scope }}</dt>
                <dd>{{ displayEnum(TEXT.enums.scopeType, selectedDocument.scope_type) }}</dd>
                <dt>{{ TEXT.modules.fileVersionManagement.columns.site }}</dt>
                <dd>{{ displaySite(selectedDocument.site_id) }}</dd>
                <dt>{{ TEXT.modules.fileVersionManagement.columns.docType }}</dt>
                <dd>{{ displayText(selectedDocument.doc_type, TEXT.enums.documentType) }}</dd>
                <dt>{{ TEXT.modules.fileVersionManagement.columns.currentVersion }}</dt>
                <dd>{{ selectedDocument.current_effective_version?.version_no || TEXT.common.fallback }}</dd>
                <dt>{{ TEXT.modules.fileVersionManagement.columns.updatedAt }}</dt>
                <dd>{{ displayDateTime(selectedDocument.updated_at) }}</dd>
              </dl>
              <div class="preview-actions">
                <el-button size="small" @click="openSelectedDocument">打开详情</el-button>
                <el-button v-if="canUpdate" size="small" :disabled="isInactiveSite(selectedDocument.site_id)" @click="openSelectedDocumentEditor">
                  {{ TEXT.common.actions.edit }}
                </el-button>
                <el-button
                  v-if="canDelete"
                  size="small"
                  type="danger"
                  plain
                  :disabled="isInactiveSite(selectedDocument.site_id)"
                  @click="deleteSelectedDocument"
                >
                  {{ TEXT.common.actions.delete }}
                </el-button>
              </div>
            </template>
            <div v-else class="preview-empty">
              <span>选择一行查看文档摘要</span>
            </div>
          </aside>
        </div>
      </section>
    </div>

    <div
      v-if="isDesktop && documentContextMenu.visible && selectedDocument"
      class="document-context-menu"
      :style="{ left: `${documentContextMenu.x}px`, top: `${documentContextMenu.y}px` }"
      @click.stop
    >
      <button type="button" @click="openSelectedDocument">打开详情</button>
      <button
        v-if="canUpdate"
        type="button"
        :disabled="isInactiveSite(selectedDocument.site_id)"
        @click="openSelectedDocumentEditor"
      >
        {{ TEXT.common.actions.edit }}
      </button>
      <button
        v-if="canDelete"
        type="button"
        class="danger"
        :disabled="isInactiveSite(selectedDocument.site_id)"
        @click="deleteSelectedDocument"
      >
        {{ TEXT.common.actions.delete }}
      </button>
    </div>

    <el-drawer
      v-if="editorVisible"
      v-model="editorVisible"
      direction="rtl"
      size="620px"
      :close-on-click-modal="true"
      :before-close="editorDirtyGuard.beforeClose"
      :show-close="false"
      destroy-on-close
      class="document-editor-drawer"
    >
      <template #header>
        <div class="editor-header">
          <div class="editor-title">{{ editingDocumentId ? TEXT.common.actions.edit : TEXT.modules.fileVersionManagement.dialog.createTitle }}</div>
        </div>
      </template>

      <el-form ref="editorFormRef" :model="editorForm" :rules="editorRules" label-position="top" class="document-form">
        <div class="form-group">
          <div class="form-group-title">
            <span class="group-dot group-dot-basic"></span>
            {{ TEXT.common.labels.basicInfo }}
          </div>
          <el-row :gutter="16">
            <el-col v-if="!editingDocumentId" :span="12">
              <el-form-item :label="TEXT.modules.fileVersionManagement.fields.docNo" prop="doc_no">
                <el-input v-model="editorForm.doc_no" placeholder="e.g. SOP-001" />
              </el-form-item>
            </el-col>
            <el-col :span="editingDocumentId ? 24 : 12">
              <el-form-item :label="TEXT.modules.fileVersionManagement.fields.title" prop="title">
                <el-input v-model="editorForm.title" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="16">
            <el-col :span="12">
              <el-form-item :label="TEXT.modules.fileVersionManagement.fields.scope" prop="scope_type">
                <el-select v-model="editorForm.scope_type" class="full-width">
                  <el-option v-for="item in scopeOptions" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item :label="TEXT.modules.fileVersionManagement.fields.docType" prop="doc_type">
                <el-select v-model="editorForm.doc_type" class="full-width">
                   <el-option v-for="item in docTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-form-item v-if="editorForm.scope_type === 'SITE'" :label="TEXT.modules.fileVersionManagement.fields.site" prop="site_id">
            <el-select v-model="editorForm.site_id" filterable class="full-width">
              <el-option v-for="item in siteOptions" :key="item.value" :label="item.label" :value="item.value" :disabled="item.disabled" />
            </el-select>
          </el-form-item>
        </div>
      </el-form>
      <template #footer>
        <div class="drawer-footer">
          <el-button @click="editorVisible = false">{{ TEXT.common.actions.cancel }}</el-button>
          <el-button type="primary" :loading="saving" @click="submitEditor">{{ TEXT.common.actions.confirm }}</el-button>
        </div>
      </template>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, reactive, ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import { ElMessage, ElMessageBox, FormInstance, FormRules } from "element-plus";
import { Plus } from "@element-plus/icons-vue";
import { fetchDocuments, createDocument, deleteDocument, updateDocument } from "../../api/documents";
import { fetchSites } from "../../api/sites";
import { useStudyStore } from "../../store/study";
import { useAuthStore } from "../../store/auth";
import { usePermission } from "../../utils/permission";
import { useDrawerDirtyGuard } from "../../utils/drawerDirtyGuard";
import type { DocumentSummary } from "../../types/documents";
import type { Site } from "../../types/api";
import { displayDateTime, displayEnum, displayText } from "../../utils/display";
import { TEXT } from "../../locales";
import { onDesktopRefreshCurrentView } from "../../composables/useDesktopRefresh";
import { isTauriRuntime } from "../../runtime";

const route = useRoute();
const router = useRouter();
const study = useStudyStore();
const auth = useAuthStore();
const { can } = usePermission();
const loading = ref(false);
const items = ref<DocumentSummary[]>([]);
const sites = ref<Site[]>([]);
const editorVisible = ref(false);
const saving = ref(false);
const editingDocumentId = ref("");
const editorFormRef = ref<FormInstance>();
const isDesktop = isTauriRuntime();
const selectedDocumentId = ref("");
const documentContextMenu = ref({ visible: false, x: 0, y: 0 });
let desktopRefreshCleanup: (() => void) | undefined;

const trialId = computed(() => (route.params.trialId as string) || "");

const filters = reactive({
  scope_type: "",
  site_id: "",
  doc_type: "",
});

const docTypeOptions = Object.keys(TEXT.enums.documentType).map((value) => ({
  value,
  label: TEXT.enums.documentType[value as keyof typeof TEXT.enums.documentType],
}));
const scopeOptions = [
  { value: "GLOBAL", label: TEXT.enums.scopeType.GLOBAL },
  { value: "SITE", label: TEXT.enums.scopeType.SITE },
];
const siteOptions = computed(() =>
  sites.value.map((site) => ({ value: site.id, label: site.name, disabled: !site.is_active }))
);
const siteActiveMap = computed(() => {
  const map: Record<string, boolean> = {};
  sites.value.forEach((site) => {
    if (site?.id) map[site.id] = !!site.is_active;
  });
  return map;
});
const isAdmin = computed(() => {
  return !!auth.user?.is_admin;
});
const canCreate = computed(() => can("documents.create"));
const canUpdate = computed(() => can("documents.update"));
const canDelete = computed(() => can("documents.delete"));
const isInactiveSite = (siteId?: string | null) => !!siteId && siteActiveMap.value[siteId] === false;
const documentRowClass = ({ row }: { row: DocumentSummary }) =>
  [
    row?.id ? "clickable-row" : "",
    isInactiveSite(row?.site_id) ? "row-inactive" : "",
    isDesktop && row?.id === selectedDocumentId.value ? "row-selected" : "",
  ]
    .filter(Boolean)
    .join(" ");
const filteredItems = computed(() =>
  items.value.filter((item) => {
    if (filters.scope_type && item?.scope_type !== filters.scope_type) return false;
    if (filters.site_id && item?.site_id !== filters.site_id) return false;
    if (filters.doc_type && item?.doc_type !== filters.doc_type) return false;
    return true;
  })
);
const sortedItems = computed(() =>
  [...filteredItems.value].sort((a, b) => Number(isInactiveSite(a?.site_id)) - Number(isInactiveSite(b?.site_id)))
);
const selectedDocument = computed(() =>
  sortedItems.value.find((item) => item.id === selectedDocumentId.value) || null
);

const editorForm = reactive({
  doc_no: "",
  title: "",
  scope_type: "GLOBAL",
  site_id: "",
  doc_type: "",
});
const editorDirtyGuard = useDrawerDirtyGuard(() => editorForm);

const editorRules: FormRules = {
  doc_no: [{ required: true, message: TEXT.common.messages.required, trigger: "blur" }],
  title: [{ required: true, message: TEXT.common.messages.required, trigger: "blur" }],
  scope_type: [{ required: true, message: TEXT.common.messages.required, trigger: "change" }],
  site_id: [
    {
      validator: (_rule, value, callback) => {
        if (editorForm.scope_type === "SITE" && !value) {
          callback(new Error(TEXT.common.messages.required));
          return;
        }
        callback();
      },
      trigger: "change",
    },
  ],
  doc_type: [{ required: true, message: TEXT.common.messages.required, trigger: "blur" }],
};

const displaySite = (siteId?: string | null) => {
  if (!siteId) return TEXT.common.fallback;
  return sites.value.find((s) => s.id === siteId)?.name || siteId;
};

const ensureTrialRoute = () => {
  if (trialId.value) return;
  const currentStudy = study.currentStudy?.id;
  if (currentStudy) {
    router.replace(`/trial/${currentStudy}/documents`);
  }
};

const loadSites = async () => {
  if (!trialId.value) return;
  try {
    const { data } = await fetchSites(trialId.value, { limit: 500 });
    const items = Array.isArray(data) ? data : data.items || [];
    sites.value = items;
  } catch {
    sites.value = [];
  }
};

const load = async () => {
  if (!trialId.value) return;
  loading.value = true;
  try {
    const { data } = await fetchDocuments({ trial_id: trialId.value });
    items.value = data.items || [];
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.message || TEXT.common.messages.loadFailed);
  } finally {
    loading.value = false;
  }
};

const resetFilters = () => {
  filters.scope_type = "";
  filters.site_id = "";
  filters.doc_type = "";
};

const resetEditorForm = () => {
  editorForm.doc_no = "";
  editorForm.title = "";
  editorForm.scope_type = "GLOBAL";
  editorForm.site_id = "";
  editorForm.doc_type = "";
  editorFormRef.value?.clearValidate();
};

const openCreate = () => {
  if (!canCreate.value) {
    ElMessage.warning("权限不足");
    return;
  }
  editingDocumentId.value = "";
  resetEditorForm();
  editorDirtyGuard.syncBaseline();
  editorVisible.value = true;
};

const openEdit = (row: DocumentSummary) => {
  if (!canUpdate.value) {
    ElMessage.warning("权限不足");
    return;
  }
  if (isInactiveSite(row.site_id)) {
    ElMessage.warning("中心已停用");
    return;
  }
  editingDocumentId.value = row.id;
  Object.assign(editorForm, {
    doc_no: "",
    title: row.title || "",
    scope_type: row.scope_type || "GLOBAL",
    site_id: row.site_id || "",
    doc_type: row.doc_type || "",
  });
  editorFormRef.value?.clearValidate();
  editorDirtyGuard.syncBaseline();
  editorVisible.value = true;
};

const submitEditor = async () => {
  if (editingDocumentId.value && !canUpdate.value) {
    ElMessage.warning("权限不足");
    return;
  }
  if (!editingDocumentId.value && !canCreate.value) {
    ElMessage.warning("权限不足");
    return;
  }
  if (!editorFormRef.value) return;
  await editorFormRef.value.validate(async (valid) => {
    if (!valid || !trialId.value) return;
    saving.value = true;
    try {
      if (editorForm.scope_type === "SITE" && isInactiveSite(editorForm.site_id)) {
        ElMessage.warning("中心已停用");
        saving.value = false;
        return;
      }
      const payload = {
        site_id: editorForm.scope_type === "SITE" ? editorForm.site_id : null,
        title: editorForm.title.trim(),
        doc_type: editorForm.doc_type,
        scope_type: editorForm.scope_type,
      };
      if (editingDocumentId.value) {
        await updateDocument(editingDocumentId.value, payload);
      } else {
        await createDocument({
          ...payload,
          trial_id: trialId.value,
          doc_no: editorForm.doc_no.trim(),
          site_id: editorForm.scope_type === "SITE" ? editorForm.site_id : undefined,
        });
      }
      editorVisible.value = false;
      await load();
      ElMessage.success(editingDocumentId.value ? TEXT.common.messages.updateSuccess : TEXT.modules.fileVersionManagement.messages.createSuccess);
    } catch (e: any) {
      ElMessage.error(e?.response?.data?.message || TEXT.common.messages.saveFailed);
    } finally {
      saving.value = false;
    }
  });
};

const goDetail = (id: string) => router.push(`/documents/${id}`);

const selectDocument = (row: DocumentSummary) => {
  if (!row?.id) return;
  selectedDocumentId.value = row.id;
};

const handleDocumentRowClick = (row: DocumentSummary) => {
  if (!row?.id) return;
  if (isDesktop) {
    selectDocument(row);
    return;
  }
  goDetail(row.id);
};

const openDocumentDetail = (row?: DocumentSummary | null) => {
  const target = row?.id ? row : selectedDocument.value;
  if (target?.id) goDetail(target.id);
};

const openSelectedDocument = () => {
  closeDocumentContextMenu();
  openDocumentDetail(selectedDocument.value);
};

const openSelectedDocumentEditor = () => {
  const target = selectedDocument.value;
  closeDocumentContextMenu();
  if (target) openEdit(target);
};

const deleteSelectedDocument = () => {
  const target = selectedDocument.value;
  closeDocumentContextMenu();
  if (target) {
    void confirmDelete(target);
  }
};

const closeDocumentContextMenu = () => {
  if (!documentContextMenu.value.visible) return;
  documentContextMenu.value = { visible: false, x: 0, y: 0 };
};

const openDocumentContextMenu = (row: DocumentSummary, _column: unknown, event: MouseEvent) => {
  if (!isDesktop || !row?.id) return;
  event.preventDefault();
  selectDocument(row);
  documentContextMenu.value = {
    visible: true,
    x: Math.min(event.clientX, window.innerWidth - 184),
    y: Math.min(event.clientY, window.innerHeight - 132),
  };
};

const confirmDelete = async (row: DocumentSummary) => {
  if (!canDelete.value) {
    ElMessage.warning("权限不足");
    return;
  }
  if (!row?.id) return;
  if (isInactiveSite(row.site_id)) {
    ElMessage.warning("中心已停用");
    return;
  }
  const ok = await ElMessageBox.confirm(TEXT.common.confirm.delete, TEXT.common.labels.tips).catch(() => null);
  if (!ok) return;
  try {
    await deleteDocument(row.id);
    ElMessage.success(TEXT.common.messages.deleteSuccess);
    await load();
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.message || TEXT.common.messages.deleteFailed);
  }
};

const splitDateTime = (value?: string | null) => {
  const displayValue = displayDateTime(value);
  const [date, time] = displayValue.split(" ");
  return { date, time: time || "" };
};

onMounted(() => {
  ensureTrialRoute();
  load();
  loadSites();
  desktopRefreshCleanup = onDesktopRefreshCurrentView(() => {
    load();
    loadSites();
  });
});

onBeforeUnmount(() => {
  desktopRefreshCleanup?.();
});

watch(
  () => trialId.value,
  (value, oldValue) => {
    if (value && value !== oldValue) {
      load();
      loadSites();
    }
  }
);

watch(
  () => sortedItems.value.map((item) => item.id).join("|"),
  () => {
    if (!isDesktop) return;
    const rows = sortedItems.value;
    if (!rows.length) {
      selectedDocumentId.value = "";
      return;
    }
    if (!rows.some((item) => item.id === selectedDocumentId.value)) {
      selectedDocumentId.value = rows[0].id;
    }
  },
  { immediate: true }
);
</script>

<style scoped>
.page {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.filter-form {
  display: flex;
  width: 100%;
  gap: 8px;
  align-items: center;
}

.filter-item-form {
  margin-bottom: 0 !important;
  margin-right: 0 !important;
}

.filter-select-comp {
  width: 132px;
}

.filter-spacer {
  flex: 1;
}

.header-action-btn {
  height: 32px;
  padding: 0 12px;
  border-radius: 10px;
}

.editor-header {
  display: flex;
  align-items: center;
}

.editor-title {
  color: var(--ctms-text-main);
  font-size: 18px;
  font-weight: 700;
}

.document-form {
  padding: 0 4px;
}

.form-group {
  padding: 16px 0;
}

.form-group-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
  color: var(--ctms-text-main);
  font-size: 15px;
  font-weight: 700;
}

.group-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
}

.group-dot-basic {
  background: var(--ctms-primary);
}

.full-width {
  width: 100%;
}

.drawer-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

/* ==================== Table Styling (DrugShipments style) ==================== */
.document-table-section {
  background: #ffffff;
  border-radius: 8px;
  overflow: hidden;
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.04),
    0 2px 8px rgba(0, 0, 0, 0.02);
}

.document-workbench {
  min-width: 0;
  min-height: 0;
}

.document-workbench.is-desktop {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 304px;
  min-height: min(570px, calc(100vh - 178px));
}

.document-table-pane {
  min-width: 0;
  outline: none;
}

.document-workbench.is-desktop .document-table-pane {
  border-right: 1px solid #e3e9f1;
}

.document-preview-pane {
  display: flex;
  min-width: 0;
  min-height: 0;
  flex-direction: column;
  gap: 16px;
  padding: 16px;
  background: #f8fafc;
}

.preview-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.preview-kicker {
  margin-bottom: 5px;
  color: #6b7e95;
  font-size: 11px;
  font-weight: 800;
}

.preview-title {
  display: -webkit-box;
  overflow: hidden;
  color: #142033;
  font-size: 17px;
  font-weight: 800;
  line-height: 1.35;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
}

.preview-list {
  display: grid;
  grid-template-columns: 76px minmax(0, 1fr);
  gap: 10px 12px;
  margin: 0;
}

.preview-list dt {
  color: #7b8da3;
  font-size: 12px;
  font-weight: 700;
}

.preview-list dd {
  min-width: 0;
  margin: 0;
  overflow-wrap: anywhere;
  color: #223349;
  font-size: 13px;
  font-weight: 650;
}

.preview-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: auto;
}

.preview-empty {
  display: flex;
  min-height: 180px;
  align-items: center;
  justify-content: center;
  color: #7b8da3;
  font-size: 13px;
  font-weight: 700;
  text-align: center;
}

.document-context-menu {
  position: fixed;
  z-index: 2300;
  display: flex;
  width: 172px;
  flex-direction: column;
  gap: 2px;
  padding: 6px;
  border: 1px solid #cbd7e5;
  border-radius: 8px;
  background: #ffffff;
  box-shadow: 0 14px 38px rgba(15, 23, 42, 0.16);
}

.document-context-menu button {
  appearance: none;
  display: flex;
  align-items: center;
  width: 100%;
  min-height: 30px;
  padding: 0 9px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: #223349;
  cursor: pointer;
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  text-align: left;
}

.document-context-menu button:hover:not(:disabled) {
  background: #eef4fb;
  color: #183756;
}

.document-context-menu button.danger {
  color: #b42318;
}

.document-context-menu button:disabled {
  cursor: not-allowed;
  color: #9aaabd;
}

.ctms-table {
  --el-table-border-color: transparent;
  --el-table-row-hover-bg-color: #f8f9fb;
}

.ctms-table :deep(.el-table__inner-wrapper::before) {
  display: none;
}

.ctms-table :deep(th.el-table__cell) {
  background: #f4f5f7;
  color: #2a2a2a;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 14px 14px;
  border-bottom: 2px solid #e0e0e0 !important;
}

.ctms-table :deep(td.el-table__cell) {
  padding: 12px 14px;
  color: #0a0a0a;
  font-size: 14px;
  font-weight: 500;
}

.ctms-table :deep(.el-table__body tr) {
  cursor: pointer;
  transition: background 0.1s ease;
}

.ctms-table :deep(.el-table__body tr.row-selected > td) {
  background: #eaf1f8 !important;
}

.ctms-table :deep(.font-semibold) {
  font-weight: 600;
  color: #0a0a0a;
}

.ctms-table :deep(.text-secondary) {
  color: #8a8a8a;
}

.ctms-table :deep(.datetime-stack) {
  display: inline-flex;
  flex-direction: column;
  gap: 2px;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  line-height: 1.25;
  white-space: nowrap;
}

.ctms-table :deep(.datetime-stack__time) {
  color: #9a9a9a;
  font-size: 11px;
}

.ctms-table :deep(.el-tag) {
  font-weight: 600;
  border: none;
}

.ctms-table :deep(.cell-actions) {
  display: flex;
  gap: 8px;
  white-space: nowrap;
}

.ctms-table :deep(.cell-actions .el-button) {
  font-size: 13px;
  padding: 0;
  height: auto;
}

.ctms-table :deep(.cell-actions .el-button + .el-button) {
  margin-left: 0;
}

:global([data-ctms-theme="dark"] .document-page--desktop .document-table-section) {
  background: #172033;
}

:global([data-ctms-theme="dark"] .document-page--desktop .document-preview-pane) {
  border-color: #26364a;
  background: #111827;
}

:global([data-ctms-theme="dark"] .document-page--desktop .preview-title),
:global([data-ctms-theme="dark"] .document-page--desktop .preview-list dd) {
  color: #f8fafc;
}

:global([data-ctms-theme="dark"] .document-page--desktop .preview-kicker),
:global([data-ctms-theme="dark"] .document-page--desktop .preview-list dt),
:global([data-ctms-theme="dark"] .document-page--desktop .preview-empty) {
  color: #94a3b8;
}

:global([data-ctms-theme="dark"] .document-page--desktop .document-context-menu) {
  border-color: #334155;
  background: #172033;
}

:global([data-ctms-theme="dark"] .document-page--desktop .document-context-menu button) {
  color: #dbe5f1;
}

:global([data-ctms-theme="dark"] .document-page--desktop .document-context-menu button:hover:not(:disabled)) {
  background: #243247;
  color: #bfdbfe;
}

:global([data-ctms-theme="dark"] .document-page--desktop .ctms-table .el-table__body tr.row-selected > td) {
  background: #243247 !important;
}
</style>

<style>
.row-inactive td {
  color: var(--ctms-text-secondary);
  background-color: #fff7d6 !important;
}

.row-inactive .el-tag {
  opacity: 0.6;
}
</style>
