<script setup lang="ts">
import { ref } from 'vue';
import {
  NButton,
  NCard,
  NCheckbox,
  NDivider,
  NFlex,
  NInput,
  NInputNumber,
  NSelect,
  NSlider,
  NTag,
  NText,
} from 'naive-ui';
import Page from '../../../../../../../packages/effects/common-ui/src/components/page/page.vue';

const emit = defineEmits<{
  prev: [];
  save: [config: SegmentConfig];
}>();

export interface SegmentConfig {
  segmentMode: 'general' | 'parent-child';
  segmentIdentifier: string;
  segmentMaxLength: number;
  segmentOverlapLength: number;
  replaceWhitespace: boolean;
  removeUrlEmail: boolean;
  useQA: boolean;
  qaLanguage: string;
  indexType: 'high' | 'economy';
  retrievalType: 'inverted' | 'vector' | 'mixed';
  topK: number;
}

const segmentMode = ref<'general' | 'parent-child'>('general');
const segmentIdentifier = ref('\\n\\n');
const segmentMaxLength = ref(1024);
const segmentOverlapLength = ref(50);
const replaceWhitespace = ref(true);
const removeUrlEmail = ref(false);
const useQA = ref(false);
const qaLanguage = ref('Chinese Simplified');
const indexType = ref<'high' | 'economy'>('high');
const retrievalType = ref<'inverted' | 'vector' | 'mixed'>('inverted');
const topK = ref(2);

const langOptions = [
  { label: 'Chinese Simplified', value: 'Chinese Simplified' },
  { label: 'English', value: 'English' },
];

function handleSave() {
  emit('save', {
    segmentMode: segmentMode.value,
    segmentIdentifier: segmentIdentifier.value,
    segmentMaxLength: segmentMaxLength.value,
    segmentOverlapLength: segmentOverlapLength.value,
    replaceWhitespace: replaceWhitespace.value,
    removeUrlEmail: removeUrlEmail.value,
    useQA: useQA.value,
    qaLanguage: qaLanguage.value,
    indexType: indexType.value,
    retrievalType: retrievalType.value,
    topK: topK.value,
  });
}
</script>

<template>
  <NFlex
    vertical
    style="
      height: 100%;
      flex-shrink: 0;
      border-right: 1px solid var(--n-border-color);
      overflow-y: auto;
    "
  >
    <NFlex vertical style="padding: 0 10px">
      <!-- 分段设置 -->
      <NText strong style="margin-bottom: 12px">分段设置</NText>

      <NFlex>
        <NCard
          hoverable
          :bordered="true"
          style="flex: 1; cursor: pointer"
          :style="segmentMode === 'general' ? 'border-color: var(--n-color-target);' : ''"
          content-style="padding: 10px 14px;"
          @click="segmentMode = 'general'"
        >
          <NText strong style="font-size: 13px">通用</NText>
          <br />
          <NText depth="3" style="font-size: 12px">适用文本分块模式，检索和已组织块后相似的</NText>
        </NCard>
      </NFlex>

      <!-- 分段参数 -->
      <NFlex>
        <NFlex vertical style="flex: 1">
          <NText style="font-size: 12px">分段标识符</NText>
          <NInput v-model:value="segmentIdentifier" size="small" />
        </NFlex>
        <NFlex vertical style="flex: 1">
          <NText style="font-size: 12px">分段最大长度</NText>
          <NInputNumber v-model:value="segmentMaxLength" size="small" :min="1" :max="4096">
            <template #suffix>
              <NText depth="3" style="font-size: 11px">characters</NText>
            </template>
          </NInputNumber>
        </NFlex>
        <NFlex vertical style="flex: 1">
          <NText style="font-size: 12px">分段重叠长度</NText>
          <NInputNumber v-model:value="segmentOverlapLength" size="small" :min="0" :max="512">
            <template #suffix>
              <NText depth="3" style="font-size: 11px">characters</NText>
            </template>
          </NInputNumber>
        </NFlex>
      </NFlex>

      <!-- 文本预处理规则 -->
      <NText style="font-size: 13px">文本预处理规则</NText>
      <NFlex vertical :gap="6" style="margin-bottom: 12px">
        <NCheckbox v-model:checked="replaceWhitespace" size="small">
          替换掉连续的空格、换行符和制表符
        </NCheckbox>
        <NCheckbox v-model:checked="removeUrlEmail" size="small">
          删除所有 URL 和电子邮件地址
        </NCheckbox>
      </NFlex>

      <NFlex align="center">
        <NCheckbox v-model:checked="useQA" size="small">使用 Q&A 分段，语言</NCheckbox>
        <NSelect
          v-model:value="qaLanguage"
          :options="langOptions"
          size="small"
          style="width: 160px"
          :disabled="!useQA"
        />
      </NFlex>

      <NFlex>
        <NButton size="small" secondary>预览块</NButton>
        <NButton size="small" secondary>重置</NButton>
      </NFlex>

      <NDivider style="margin: 0 0 2px" />

      <!-- 父子分段 -->
      <NText strong>父子分段</NText>
      <NText depth="3" style="font-size: 12px">
        适用子分段模式；父块用于生成索引，父块在父级为上下文
      </NText>

      <NDivider style="margin: 0 0 2px" />

      <!-- 索引方式 -->
      <NText strong>索引方式</NText>
      <NFlex>
        <NCard
          hoverable
          :bordered="true"
          style="flex: 1; cursor: pointer"
          :style="indexType === 'high' ? 'border-color: var(--n-color-target);' : ''"
          content-style="padding: 10px 14px;"
          @click="indexType = 'high'"
        >
          <NFlex align="center">
            <NText strong style="font-size: 13px">高质量</NText>
            <NTag size="tiny" type="info">推荐</NTag>
          </NFlex>
          <NText depth="3" style="font-size: 12px">
            在调用模型处理后以实现更高度的精确搜索，可以让 LLM 生成高质量的面答。
          </NText>
        </NCard>
        <NCard
          hoverable
          :bordered="true"
          style="flex: 1; cursor: pointer"
          :style="indexType === 'economy' ? 'border-color: var(--n-color-target);' : ''"
          content-style="padding: 10px 14px;"
          @click="indexType = 'economy'"
        >
          <NText strong style="font-size: 13px; display: block">经济</NText>
          <NText depth="3" style="font-size: 12px">
            离于关键词快但仅 10 个关键词进行检索，不会消耗任何 tokens，也以以向临低取额偿性代替。
          </NText>
        </NCard>
      </NFlex>

      <NDivider style="margin: 0 0 2px" />

      <!-- 检索设置 -->
      <NText strong>检索设置</NText>
      <NText depth="3" style="font-size: 12px">
        新建发生于不检索方法，供以判断对你的应用是管中采此此设置。
      </NText>

      <NCard
        hoverable
        :bordered="true"
        style="cursor: pointer"
        :style="retrievalType === 'inverted' ? 'border-color: var(--n-color-target);' : ''"
        content-style="padding: 10px 14px;"
        @click="retrievalType = 'inverted'"
      >
        <NText strong style="font-size: 13px; display: block">倒排索引</NText>
        <NText depth="3" style="font-size: 12px">
          倒排索引是一种检索数据结构的组织，把每个关键词，每个关键词都会有它们自己链接的文段继续填写
        </NText>
      </NCard>

      <NFlex align="center">
        <NText style="font-size: 12px; white-space: nowrap">Top K</NText>
        <NSlider v-model:value="topK" :min="1" :max="20" style="flex: 1" />
        <NText style="min-width: 18px; text-align: left">{{ topK }}</NText>
      </NFlex>

      <!-- 操作按钮 -->
      <NFlex justify="space-between" style="padding-bottom: 24px">
        <NButton secondary @click="emit('prev')">← 上一步</NButton>
        <NButton type="primary" @click="handleSave">保存并处理</NButton>
      </NFlex>
    </NFlex>
  </NFlex>
</template>
