<script setup lang="ts">
import { CirclePlus, Delete, Edit, FolderAdd, Refresh, Search, UploadFilled } from '@element-plus/icons-vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { computed, onMounted, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import { loadModelProviderEnumOptions, type EnumOption } from '@/api/modelEnums';
import {
  getRagStoreModelConfig,
  queryModelConfigs,
  rebuildRagStoreIndex,
  saveRagStoreModelConfig,
  type ModelConfig,
} from '@/api/modelProvider';

import {
  deleteRagStore,
  getRagStoreById,
  getRagStoreDocumentOverview,
  getRagStoreOverview,
  queryRagStores,
  saveRagStore,
  type RagStoreDocumentOverview,
  type RagStoreOverview,
  type RagStore,
} from '@/api/ragStores';
import RagDocumentBatchUploadDialog from '@/components/rag/RagDocumentBatchUploadDialog.vue';

type StoreStatus = '启用' | '停用';

const router = useRouter();
const loading = ref(false);
const detailLoading = ref(false);
const submitting = ref(false);
const storeRows = ref<RagStore[]>([]);
const activeStoreId = ref<string | null>(null);
const activeStore = ref<RagStore | null>(null);
const pageOverview = ref<RagStoreOverview | null>(null);
const activeStoreDocumentOverview = ref<RagStoreDocumentOverview | null>(null);
const embeddingModels = ref<ModelConfig[]>([]);
const ragConfigLoading = ref(false);
const ragConfigSaving = ref(false);
const ragConfig = reactive({
  id: '',
  embeddingModelId: '',
  embeddingDimension: 1024,
  chunkStrategy: null as number | null,
  chunkSize: null as number | null,
  chunkOverlap: null as number | null,
  delimiter: '',
  remark: '',
});
const chunkStrategyOptions = ref<EnumOption[]>([]);

const queryForm = reactive({
  storeName: '',
});

const createDialogVisible = ref(false);
const editDialogVisible = ref(false);
const uploadDialogVisible = ref(false);

const createForm = reactive({
  storeCode: '',
  storeName: '',
  description: '',
  status: '启用' as StoreStatus,
  remark: '',
});

const editForm = reactive({
  id: '',
  storeCode: '',
  storeName: '',
  description: '',
  status: '启用' as StoreStatus,
  remark: '',
});

const overviewCards = computed(() => {
  const totalStores = pageOverview.value?.totalStores ?? storeRows.value.length;
  const totalDocuments = pageOverview.value?.totalDocuments ?? '-';
  const totalChunks = pageOverview.value?.totalChunks ?? '-';
  const retrievableStores =
    pageOverview.value?.retrievableStores
    ?? storeRows.value.filter((row) => row.status === '启用').length;

  return [
    { label: '知识库总数', value: totalStores, hint: '当前已登记知识库' },
    { label: '文档总数', value: totalDocuments, hint: '当前知识库已登记文档总量' },
    { label: '切片总数', value: totalChunks, hint: '当前未接入切片表，待后续能力补充' },
    { label: '可检索知识库数', value: retrievableStores, hint: '当前按启用状态统计' },
  ];
});

async function loadOverview() {
  try {
    const response = await getRagStoreOverview();
    pageOverview.value = response.data ?? null;
  } catch {
    pageOverview.value = null;
  }
}

async function loadStores(preferredStoreId?: string | null) {
  loading.value = true;
  try {
    const response = await queryRagStores({
      storeName: queryForm.storeName.trim() || undefined,
    });
    storeRows.value = response.data ?? [];

    if (storeRows.value.length === 0) {
      activeStoreId.value = null;
      activeStore.value = null;
      activeStoreDocumentOverview.value = null;
      ragConfig.id = '';
      ragConfig.embeddingModelId = '';
      return;
    }

    const firstStore = storeRows.value[0];
    const targetId =
      preferredStoreId && storeRows.value.some((row) => String(row.id) === preferredStoreId)
        ? preferredStoreId
        : firstStore
          ? String(firstStore.id)
          : null;
    if (!targetId) {
      activeStoreId.value = null;
      activeStore.value = null;
      activeStoreDocumentOverview.value = null;
      return;
    }
    await selectStore(targetId);
  } finally {
    loading.value = false;
  }
}

async function selectStore(storeId: string) {
  activeStoreId.value = storeId;
  detailLoading.value = true;
  try {
    const [storeResponse, documentOverviewResponse] = await Promise.all([
      getRagStoreById(storeId),
      getRagStoreDocumentOverview(storeId),
    ]);
    activeStore.value = storeResponse.data ?? null;
    activeStoreDocumentOverview.value = documentOverviewResponse.data ?? null;
    await loadRagModelConfig(storeId);
  } finally {
    detailLoading.value = false;
  }
}

function handleSearch() {
  loadStores(activeStoreId.value);
}

function handleReset() {
  queryForm.storeName = '';
  loadStores();
}

function openCreateDialog() {
  createForm.storeCode = '';
  createForm.storeName = '';
  createForm.description = '';
  createForm.status = '启用';
  createForm.remark = '';
  createDialogVisible.value = true;
}

function openEditDialog() {
  if (!activeStore.value) {
    return;
  }

  editForm.id = String(activeStore.value.id ?? '');
  editForm.storeCode = activeStore.value.storeCode;
  editForm.storeName = activeStore.value.storeName;
  editForm.description = activeStore.value.description ?? '';
  editForm.status = (activeStore.value.status as StoreStatus) || '启用';
  editForm.remark = activeStore.value.remark ?? '';
  editDialogVisible.value = true;
}

async function submitCreateStore() {
  if (!createForm.storeCode || !createForm.storeName) {
    ElMessage.warning('请填写知识库编码和知识库名称');
    return;
  }

  submitting.value = true;
  try {
    await saveRagStore({
      storeCode: createForm.storeCode,
      storeName: createForm.storeName,
      description: createForm.description,
      status: createForm.status,
      remark: createForm.remark,
    });
    createDialogVisible.value = false;
    ElMessage.success('知识库已创建');
    await loadStores();
  } finally {
    submitting.value = false;
  }
}

async function submitEditStore() {
  if (!editForm.id || !editForm.storeCode || !editForm.storeName) {
    ElMessage.warning('请填写知识库编码和知识库名称');
    return;
  }

  submitting.value = true;
  try {
    await saveRagStore({
      id: editForm.id,
      storeCode: editForm.storeCode,
      storeName: editForm.storeName,
      description: editForm.description,
      status: editForm.status,
      remark: editForm.remark,
    });
    editDialogVisible.value = false;
    ElMessage.success('知识库信息已更新');
    await loadStores(editForm.id);
  } finally {
    submitting.value = false;
  }
}

async function removeStore() {
  if (!activeStore.value?.id) {
    return;
  }

  await ElMessageBox.confirm(`确认删除知识库「${activeStore.value.storeName}」？`, '删除确认', {
    type: 'warning',
    confirmButtonText: '删除',
    cancelButtonText: '取消',
  });

  await deleteRagStore(String(activeStore.value.id));
  ElMessage.success('知识库已删除');
  await loadStores();
}

function openBatchUploadDialog() {
  if (!activeStore.value?.id) {
    ElMessage.warning('请选择知识库');
    return;
  }
  uploadDialogVisible.value = true;
}

function viewActiveStoreDocuments() {
  if (!activeStore.value?.id) {
    return;
  }
  router.push({
    name: 'rag-documents',
    query: { storeId: String(activeStore.value.id) },
  });
}

async function refreshAfterUpload() {
  await Promise.all([
    loadOverview(),
    activeStoreId.value ? selectStore(activeStoreId.value) : Promise.resolve(),
  ]);
}

async function loadRagModelConfig(storeId: string) {
  ragConfigLoading.value = true;
  try {
    const response = await getRagStoreModelConfig(storeId);
    const data = response.data;
    ragConfig.id = data?.id ?? '';
    ragConfig.embeddingModelId = data?.embeddingModelId ?? '';
    ragConfig.embeddingDimension = data?.embeddingDimension ?? 1024;
    ragConfig.chunkStrategy = data?.chunkStrategy ?? null;
    ragConfig.chunkSize = data?.chunkSize ?? null;
    ragConfig.chunkOverlap = data?.chunkOverlap ?? null;
    ragConfig.delimiter = data?.delimiter ?? '';
    ragConfig.remark = data?.remark ?? '';
  } finally {
    ragConfigLoading.value = false;
  }
}

async function saveStoreModelConfig() {
  if (!activeStoreId.value) {
    return;
  }
  if (!ragConfig.embeddingModelId) {
    ElMessage.warning('请选择 Embedding 模型');
    return;
  }
  ragConfigSaving.value = true;
  try {
    await saveRagStoreModelConfig({
      id: ragConfig.id || undefined,
      storeId: activeStoreId.value,
      embeddingModelId: ragConfig.embeddingModelId,
      embeddingDimension: ragConfig.embeddingDimension,
      chunkStrategy: ragConfig.chunkStrategy ?? undefined,
      chunkSize: ragConfig.chunkSize ?? undefined,
      chunkOverlap: ragConfig.chunkOverlap ?? undefined,
      delimiter: ragConfig.delimiter || undefined,
      remark: ragConfig.remark || undefined,
    });
    ElMessage.success('知识库模型配置已保存');
    await loadRagModelConfig(activeStoreId.value);
  } finally {
    ragConfigSaving.value = false;
  }
}

async function triggerRebuildIndex() {
  if (!activeStoreId.value) {
    return;
  }
  await rebuildRagStoreIndex(activeStoreId.value);
  ElMessage.success('已触发重建索引');
}

function syncEmbeddingDimensionFromModel() {
  const model = embeddingModels.value.find((item) => item.id === ragConfig.embeddingModelId);
  if (!model) {
    return;
  }
  if (model.embeddingDimension) {
    ragConfig.embeddingDimension = model.embeddingDimension;
  }
}

function getStatusTagType(status?: string | null) {
  return status === '启用' ? 'success' : 'info';
}

onMounted(() => {
  Promise.all([
    loadOverview(),
    loadStores(),
    queryModelConfigs().then((response) => {
      embeddingModels.value = (response.data ?? []).filter((item) => item.modelType === 'EMBEDDING');
    }),
    loadModelProviderEnumOptions().then((enums) => {
      chunkStrategyOptions.value = enums.chunk_strategy ?? [];
    }),
  ]);
});
</script>

<template>
  <section class="page-panel rag-store-page">
    <div class="page-panel__header rag-store-page__header">
      <div>
        <h2>知识库</h2>
        <p>统一管理知识库及其文档、索引状态</p>
      </div>
      <span>RAG Stores</span>
    </div>

    <div class="overview-grid">
      <article v-for="card in overviewCards" :key="card.label" class="overview-card">
        <span class="overview-card__label">{{ card.label }}</span>
        <strong class="overview-card__value">{{ card.value }}</strong>
        <small class="overview-card__hint">{{ card.hint }}</small>
      </article>
    </div>

    <div class="rag-store-page__content">
      <section class="store-list-panel">
        <div class="section-heading">
          <div>
            <h3>知识库列表</h3>
            <p>按知识库名称检索并切换当前查看对象</p>
          </div>
          <el-button data-test="create-store" type="primary" :icon="CirclePlus" @click="openCreateDialog">
            新建知识库
          </el-button>
        </div>

        <div class="store-search-bar">
          <el-input
            v-model="queryForm.storeName"
            data-test="store-name-input"
            clearable
            placeholder="请输入知识库名称"
            @keyup.enter="handleSearch"
          />
          <el-button data-test="store-search" type="primary" :icon="Search" @click="handleSearch">
            查询
          </el-button>
          <el-button :icon="Refresh" @click="handleReset">重置</el-button>
        </div>

        <div v-loading="loading" class="store-list">
          <button
            v-for="store in storeRows"
            :key="store.id"
            :data-test="`store-card-${String(store.storeCode).toLowerCase()}`"
            class="store-card"
            :class="{ 'store-card--active': String(store.id) === activeStoreId }"
            type="button"
            @click="selectStore(String(store.id))"
          >
            <div class="store-card__title-row">
              <strong>{{ store.storeName }}</strong>
              <el-tag size="small" :type="getStatusTagType(store.status)">{{ store.status || '未设置' }}</el-tag>
            </div>
            <p>编码：{{ store.storeCode }}</p>
            <div class="store-card__metrics">
              <span>描述：{{ store.description || '暂无描述' }}</span>
            </div>
            <div class="store-card__metrics">
              <span>更新时间：{{ store.updateTime || '-' }}</span>
            </div>
          </button>

          <el-empty v-if="!loading && storeRows.length === 0" description="未找到匹配的知识库" />
        </div>
      </section>

      <section class="store-detail-panel">
        <div v-loading="detailLoading" class="store-detail-panel__body">
          <template v-if="activeStore">
            <div class="section-heading section-heading--detail">
              <div>
                <h3>{{ activeStore.storeName }}</h3>
                <p>编码：{{ activeStore.storeCode }}</p>
              </div>
              <div class="detail-actions">
                <el-button :icon="Edit" @click="openEditDialog">编辑</el-button>
                <el-button
                  data-test="store-batch-upload"
                  type="primary"
                  :icon="UploadFilled"
                  @click="openBatchUploadDialog"
                >
                  批量导入文件
                </el-button>
                <el-button :icon="FolderAdd" @click="triggerRebuildIndex">重建索引</el-button>
                <el-button type="danger" :icon="Delete" @click="removeStore">删除</el-button>
              </div>
            </div>

            <div class="detail-grid">
              <article class="detail-card">
                <div class="detail-card__header">
                  <h4>基本信息</h4>
                  <el-tag :type="getStatusTagType(activeStore.status)">{{ activeStore.status || '未设置' }}</el-tag>
                </div>
                <el-descriptions :column="2" border>
                  <el-descriptions-item label="知识库名称">
                    {{ activeStore.storeName }}
                  </el-descriptions-item>
                  <el-descriptions-item label="知识库编码">
                    {{ activeStore.storeCode }}
                  </el-descriptions-item>
                  <el-descriptions-item label="描述" :span="2">
                    {{ activeStore.description || '暂无描述' }}
                  </el-descriptions-item>
                  <el-descriptions-item label="备注" :span="2">
                    {{ activeStore.remark || '暂无备注' }}
                  </el-descriptions-item>
                  <el-descriptions-item label="创建时间">
                    {{ activeStore.createTime || '-' }}
                  </el-descriptions-item>
                  <el-descriptions-item label="更新时间">
                    {{ activeStore.updateTime || '-' }}
                  </el-descriptions-item>
                </el-descriptions>
              </article>

              <article class="detail-card detail-card--placeholder">
                <div class="detail-card__header">
                  <h4>文档概览</h4>
                  <el-button
                    data-test="view-store-documents"
                    link
                    type="primary"
                    @click="viewActiveStoreDocuments"
                  >
                    查看文档
                  </el-button>
                </div>
                <el-descriptions :column="2" border>
                  <el-descriptions-item label="文档总数">
                    {{ activeStoreDocumentOverview?.documentCount ?? 0 }}
                  </el-descriptions-item>
                  <el-descriptions-item label="启用文档数">
                    {{ activeStoreDocumentOverview?.enabledDocumentCount ?? 0 }}
                  </el-descriptions-item>
                  <el-descriptions-item label="已解析文档数">
                    {{ activeStoreDocumentOverview?.parsedDocumentCount ?? 0 }}
                  </el-descriptions-item>
                  <el-descriptions-item label="已索引文档数">
                    {{ activeStoreDocumentOverview?.indexedDocumentCount ?? 0 }}
                  </el-descriptions-item>
                  <el-descriptions-item label="最近上传时间" :span="2">
                    {{ activeStoreDocumentOverview?.lastUploadTime || '-' }}
                  </el-descriptions-item>
                </el-descriptions>
              </article>

              <article class="detail-card">
                <div class="detail-card__header">
                  <h4>检索配置</h4>
                  <el-button type="primary" link :loading="ragConfigSaving" @click="saveStoreModelConfig">
                    保存配置
                  </el-button>
                </div>
                <div v-loading="ragConfigLoading" class="rag-config-form">
                  <el-form :model="ragConfig" label-width="112px">
                    <el-form-item label="Embedding 模型" required>
                      <el-select
                        v-model="ragConfig.embeddingModelId"
                        placeholder="请选择模型"
                        @change="syncEmbeddingDimensionFromModel"
                      >
                        <el-option
                          v-for="item in embeddingModels"
                          :key="item.id"
                          :label="`${item.modelName}(${item.modelCode})`"
                          :value="item.id"
                        />
                      </el-select>
                    </el-form-item>
                    <el-form-item label="向量维度">
                      <el-input-number v-model="ragConfig.embeddingDimension" :min="1" controls-position="right" />
                    </el-form-item>
                    <el-form-item label="切片策略">
                      <el-select v-model="ragConfig.chunkStrategy" clearable placeholder="可选">
                        <el-option
                          v-for="item in chunkStrategyOptions"
                          :key="item.value"
                          :label="item.label"
                          :value="Number(item.value)"
                        />
                      </el-select>
                    </el-form-item>
                    <el-form-item label="切片大小">
                      <el-input-number v-model="ragConfig.chunkSize" :min="1" controls-position="right" />
                    </el-form-item>
                    <el-form-item label="切片重叠">
                      <el-input-number v-model="ragConfig.chunkOverlap" :min="0" controls-position="right" />
                    </el-form-item>
                    <el-form-item label="分隔符">
                      <el-input v-model="ragConfig.delimiter" placeholder="可选，如 \\n\\n" />
                    </el-form-item>
                    <el-form-item label="备注">
                      <el-input v-model="ragConfig.remark" type="textarea" :rows="2" />
                    </el-form-item>
                  </el-form>
                </div>
              </article>

              <article class="detail-card detail-card--placeholder">
                <div class="detail-card__header">
                  <h4>最近任务</h4>
                  <span>下一批接口补充</span>
                </div>
                <el-empty description="导入任务、索引任务与状态流转待后端补充" />
              </article>
            </div>
          </template>

          <el-empty v-else description="请选择左侧一个知识库查看详情" />
        </div>
      </section>
    </div>

    <el-dialog v-model="createDialogVisible" title="新建知识库" width="560px">
      <el-form :model="createForm" label-width="96px">
        <el-form-item label="知识库编码" required>
          <el-input v-model="createForm.storeCode" data-test="create-store-code" placeholder="如 PROD_DOC" />
        </el-form-item>
        <el-form-item label="知识库名称" required>
          <el-input
            v-model="createForm.storeName"
            data-test="create-store-name"
            placeholder="请输入知识库名称"
          />
        </el-form-item>
        <el-form-item label="状态">
          <el-radio-group v-model="createForm.status">
            <el-radio-button label="启用" />
            <el-radio-button label="停用" />
          </el-radio-group>
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model="createForm.description" type="textarea" :rows="3" placeholder="请输入知识库描述" />
        </el-form-item>
        <el-form-item label="备注">
          <el-input v-model="createForm.remark" type="textarea" :rows="2" placeholder="可选" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="createDialogVisible = false">取消</el-button>
        <el-button data-test="create-store-submit" type="primary" :loading="submitting" @click="submitCreateStore">
          保存
        </el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="editDialogVisible" title="编辑知识库" width="560px">
      <el-form :model="editForm" label-width="96px">
        <el-form-item label="知识库编码" required>
          <el-input v-model="editForm.storeCode" />
        </el-form-item>
        <el-form-item label="知识库名称" required>
          <el-input v-model="editForm.storeName" />
        </el-form-item>
        <el-form-item label="状态">
          <el-radio-group v-model="editForm.status">
            <el-radio-button label="启用" />
            <el-radio-button label="停用" />
          </el-radio-group>
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model="editForm.description" type="textarea" :rows="3" />
        </el-form-item>
        <el-form-item label="备注">
          <el-input v-model="editForm.remark" type="textarea" :rows="2" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="editDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="submitting" @click="submitEditStore">保存</el-button>
      </template>
    </el-dialog>

    <RagDocumentBatchUploadDialog
      v-model="uploadDialogVisible"
      :stores="activeStore ? [activeStore] : storeRows"
      :locked-store-id="activeStoreId"
      @uploaded="refreshAfterUpload"
    />
  </section>
</template>

<style scoped>
.rag-store-page {
  display: flex;
  flex-direction: column;
}

.rag-store-page__header {
  align-items: flex-start;
}

.rag-store-page__header p {
  margin: 6px 0 0;
  color: #667085;
  font-size: 13px;
}

.overview-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
  padding: 20px 22px 0;
}

.overview-card {
  border: 1px solid #e6ebf3;
  border-radius: 12px;
  padding: 18px 18px 16px;
  background: linear-gradient(180deg, #ffffff, #f9fbff);
  box-shadow: 0 6px 20px rgba(15, 23, 42, 0.04);
}

.overview-card__label {
  display: block;
  color: #667085;
  font-size: 13px;
  font-weight: 600;
}

.overview-card__value {
  display: block;
  margin-top: 8px;
  color: #172033;
  font-size: 28px;
  font-weight: 700;
}

.overview-card__hint {
  display: block;
  margin-top: 8px;
  color: #98a2b3;
  font-size: 12px;
}

.rag-store-page__content {
  display: grid;
  grid-template-columns: minmax(320px, 0.95fr) minmax(0, 1.45fr);
  gap: 18px;
  padding: 18px 22px 22px;
  min-height: 0;
  flex: 1;
}

.store-list-panel,
.store-detail-panel {
  border: 1px solid #e6ebf3;
  border-radius: 12px;
  background: #fcfdff;
  overflow: hidden;
}

.store-detail-panel__body {
  min-height: 100%;
}

.section-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 18px 18px 14px;
  border-bottom: 1px solid #eef2f7;
  background: linear-gradient(180deg, #ffffff, #fbfcff);
}

.section-heading h3 {
  margin: 0;
  color: #172033;
  font-size: 17px;
}

.section-heading p {
  margin: 6px 0 0;
  color: #667085;
  font-size: 13px;
}

.store-search-bar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 10px;
  padding: 16px 18px;
  border-bottom: 1px solid #eef2f7;
  background: #ffffff;
}

.store-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 18px;
  max-height: 780px;
  overflow: auto;
}

.store-card {
  border: 1px solid #e3e8f0;
  border-radius: 12px;
  padding: 16px;
  text-align: left;
  background: #ffffff;
  cursor: pointer;
  transition:
    border-color 0.2s ease,
    box-shadow 0.2s ease,
    transform 0.2s ease;
}

.store-card:hover {
  border-color: #bfdbfe;
  box-shadow: 0 8px 22px rgba(22, 119, 255, 0.08);
  transform: translateY(-1px);
}

.store-card--active {
  border-color: #1677ff;
  box-shadow: 0 10px 24px rgba(22, 119, 255, 0.12);
  background: #f7fbff;
}

.store-card__title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.store-card strong {
  color: #172033;
  font-size: 16px;
}

.store-card p {
  margin: 10px 0 0;
  color: #475467;
  font-size: 13px;
}

.store-card__metrics {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
  color: #667085;
  font-size: 13px;
  flex-wrap: wrap;
}

.section-heading--detail {
  align-items: flex-start;
}

.detail-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.detail-grid {
  display: grid;
  gap: 16px;
  padding: 18px;
}

.detail-card {
  border: 1px solid #e7edf5;
  border-radius: 12px;
  background: #ffffff;
  padding: 16px;
}

.detail-card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.detail-card__header h4 {
  margin: 0;
  color: #172033;
  font-size: 15px;
}

.detail-card__header span {
  color: #667085;
  font-size: 12px;
}

.detail-card--placeholder :deep(.el-empty) {
  padding: 12px 0;
}

.rag-config-form :deep(.el-select),
.rag-config-form :deep(.el-input-number) {
  width: 100%;
}

@media (max-width: 1280px) {
  .overview-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .rag-store-page__content {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 768px) {
  .overview-grid {
    grid-template-columns: 1fr;
    padding: 16px 16px 0;
  }

  .rag-store-page__content {
    padding: 16px;
  }

  .section-heading,
  .section-heading--detail {
    flex-direction: column;
    align-items: stretch;
  }

  .store-search-bar {
    grid-template-columns: 1fr;
  }

  .detail-actions {
    justify-content: flex-start;
  }
}
</style>
