<template>
  <div class="setting-form">
    <h5 class="setting-form-title">模型设置</h5>
    <ul>
      <!--模型-->
      <li class="setting-form-item flex-between">
        <span class="setting-form-label">模型</span>
        <el-select class="ml-30" v-model="answerSetting.info.model">
          <template #label="{ value }">
            <div class="flex align-center">
              <span v-html="modelToIcon" style="width: 13px;" class="mr-8"></span>
              {{ modelToName }}
            </div>
          </template>
          <el-option v-for="model in modelList" :key="model.name" :value="model.key" :label="model.name">
            <div class="flex align-center">
              <span v-html="model.icon" style="width: 13px;" class="mr-8"></span>
              {{ model.name }}
            </div>
          </el-option>
        </el-select>
      </li>
      <!--生成随机性-->
      <li class="setting-form-item flex-between">
        <span class="setting-form-label">
          生成随机性
          <el-tooltip effect="dark" content="调高温度会使得模型的输出更多样性和创新性，反之，降低温度会使输出内容更加遵循指令要求但減少多样性。建议不要与“Topp”同时调整。"
            placement="top">
            <lz-svg-icon icon-class="tishi" class="tip-icon" />
          </el-tooltip>
        </span>
        <el-slider :step="0.01" :min="0" :max="1" v-model="answerSetting.info.random" show-input />
      </li>
      <!--携带上下文轮数-->
      <li class="setting-form-item flex-between">
        <span class="setting-form-label">
          携带上下文轮数
          <el-tooltip effect="dark" content="设置带入模型上下文的对话历史轮数。轮数越多，多轮对话的相关性越高，但消耗的 Token 也越多。" placement="top">
            <lz-svg-icon icon-class="tishi" class="tip-icon" />
          </el-tooltip>
        </span>
        <el-slider :min="0" :max="100" v-model="answerSetting.info.circles" show-input />
      </li>
      <!--最大回复长度-->
      <li class="setting-form-item flex-between">
        <span class="setting-form-label">
          最大回复长度
          <el-tooltip effect="dark" content="控制模型输出的 Tokens 长度上限。通常 100 Tokens 约等于150 个中文汉字。" placement="top">
            <lz-svg-icon icon-class="tishi" class="tip-icon" />
          </el-tooltip>
        </span>
        <el-slider :min="0" :max="12288" v-model="answerSetting.info.replayLength" show-input />
      </li>
      <!--SP防泄漏指令-->
      <li class="setting-form-item flex-between">
        <span class="setting-form-label">
          知识库信源模式
          <el-tooltip effect="dark" content="开启后，模型的回答将仅限于从关联的知识库中提取内容，确保信息来源的准确性" placement="top">
            <lz-svg-icon icon-class="tishi" class="tip-icon" />
          </el-tooltip>
        </span>
        <el-switch v-model="answerSetting.info.spStatus" />
      </li>
      <!--展示思考过程-->
      <li class="setting-form-item flex-between" v-if="thoughtProcess">
        <span class="setting-form-label">展示思考过程</span>
        <el-switch v-model="answerSetting.info.showThinkStatus" />
      </li>
    </ul>
    <!--分割线-->
    <el-divider />
    <h5 class="setting-form-title">智能体配置</h5>
    <ul>
      <li class="setting-form-item">
        <span class="setting-form-label">开场白</span>
        <el-input class="mt-8" type="textarea" v-model="answerSetting.info.opening" :rows="5" placeholder="请输入开场白"
          resize="none" show-word-limit maxlength="300" />
      </li>
      <!--引导问题-->
      <li class="setting-form-item">
        <span class="setting-form-label flex-between">
          引导问题
          <a class="btn-add" @click="handleInsertQuestionGuide">添加</a>
        </span>
        <el-row>
          <el-col :span="24">
            <VueDraggable ref="el" v-model="compQuestions">
              <div v-for="(item, index) in compQuestions" :key="item.id" class="question-guide flex-between" :data-uuid="item.id">
                <lz-svg-icon icon-class="move" class="question-guide-left" />
                <el-input v-model="item.name" placeholder="请输入引导问题">
                  <template #suffix>
                    <lz-svg-icon icon-class="shanchu" class="cursor" @click="removeQuestionGuide(index)" />
                  </template>
                </el-input>
              </div>
            </VueDraggable>
          </el-col>
        </el-row>
      </li>
      <!--提示词-->
      <li class="setting-form-item">
        <span class="setting-form-label flex-between">
          提示词
          <a class="btn-add" @click="handleOpenTag">插入标签</a>
        </span>
        <tag-input-wrapper ref="tagInputRef" :initValue="answerSetting.info.reminder"  class="mt-8" />
      </li>
      <!--关联知识库-->
      <li class="setting-form-item">
        <span class="setting-form-label flex-between">
          关联知识库
          <a class="btn-add" @click="handleOpenDataset">选择知识库</a>
        </span>
        <div v-for="(item, index) in answerSetting.info.knowledgeIds" :key="index" class="question-guide flex-between">
          <el-input v-model="item.name"  readonly @click.stop>
            <template #suffix>
              <lz-svg-icon icon-class="shanchu1" class="cursor" style="color: #999;" @click="removeQuestionKnowledge(index)" />
            </template>
          </el-input>
        </div>
      </li>
    </ul>
    <!--选中标签-->
    <DialogTag ref="dialogTagRef" @submitHandle="submitTagHandle" />
    <!--关联知识库-->
    <DialogDataset ref="dialogDatasetRef" @submitHandle="submitDatasetHandle" :ids="answerSetting?.info?.knowledgeIds?.map(item => item.id) || []"/>
  </div>
</template>

<script lang="ts" setup>
import { ref, computed, onMounted, watch } from 'vue'
import { VueDraggable } from 'vue-draggable-plus'
import DialogTag from '@/views/knowledge/components/DialogTag.vue'
import DialogDataset from '@/views/knowledge/components/DialogDataset.vue'
import { list1 } from '@/servers/finyx/api/aIyingyongmoxing';

import { generateId } from '@/utils/uuid'
import useStore from '@/stores'

const { answerSetting } = useStore()

const tagInputRef = ref<any>(null)
const dialogTagRef = ref<any>(null)
const dialogDatasetRef = ref<any>(null)
const modelList = ref<any>([])

/** 引导问题-计算属性 */
const compQuestions = computed({
  get() {
    return answerSetting.info?.questions || []
  },
  set(value) {
    if (answerSetting.info) {
      answerSetting.info.questions = value
    }
  }
})

/** 获取模型列表 */
const getModelList = () => {
  list1({}).then((res: any) => {
    modelList.value = res
  })
} 
/** 打开-关联知识库弹框 */
const handleOpenDataset = () => {
  dialogDatasetRef.value.open()
}
/** 提交-关联知识库 */
const submitDatasetHandle = (ids: any, selectionList: any) => {
  console.log('[ 关联知识库 ]', ids, selectionList)
  const data = selectionList;
  answerSetting.info.knowledgeIds = data
  dialogDatasetRef.value.close()
}

/** 删除- 关联知识库 */
const removeQuestionKnowledge = (index: number) => {
  answerSetting.info.knowledgeIds?.splice(index, 1)
}

/** 打开-标签弹框 */
const handleOpenTag = () => {
  dialogTagRef.value.open()
}

/** 提交-标签弹框 */
const submitTagHandle = (ids: any, items: any) => {
  const data = items.map((el: any) => {
    return {
      name: el.name + '+' + el.wName,
      id: el.wId
    }
  })
  tagInputRef.value.insertTags(data)
  dialogTagRef.value.close()
}

/** 解析模型icon图标 */
const modelToIcon = computed(() => {
  return modelList.value.find((item: any) => item.key === answerSetting.info.model)?.icon
})

/** 解析模型名称 */
const modelToName = computed(() => {
  return modelList.value.find((item:any) => item.key === answerSetting.info.model)?.name
})

/** 是否展示思考过程 */
const thoughtProcess = computed(() => {
  return modelList.value.find((item:any) => item.key === answerSetting.info.model)?.thoughtProcess || false
})


/** 添加-引导问题 */
const handleInsertQuestionGuide = () => {
  if (!answerSetting.info) {
    answerSetting.info = { questions: [] }
  }
  if (!answerSetting.info.questions) {
    answerSetting.info.questions = []
  }
  answerSetting.info.questions.push({ name: '', id: generateId()})
}

/** 删除-引导问题 */
const removeQuestionGuide = (index: number) => {
  if (answerSetting.info?.questions) {
    answerSetting.info.questions.splice(index, 1)
  }
}

const getParams = () => {
  /** 获取提示词内容 */
  const htmlStr = tagInputRef.value.getHtml()
  /** 转换为约定的格式 {名称:id} */
  const reminder = tagInputRef.value.parseHtml(htmlStr) // 提示词
   /** 提取字符串中的对象 */
  const labelIds = tagInputRef.value.extractTagsFromString(reminder); // 提示词-标签
  /** 过滤 引导问题为空 */
  const questions = answerSetting.info?.questions?.filter((item: any) => item.name.length > 0)  
  return {
    ...answerSetting.info,
    reminder,
    labelIds,
    questions,
  }
}

watch(() => answerSetting.info.model, (newVal) => {
  if (newVal) {
    answerSetting.info.showThinkStatus = false
  }
})

onMounted(() => { 
  getModelList()
})

defineExpose({
  getParams,
  handleInsertQuestionGuide,
})

</script>

<style lang="scss" scoped>
.setting-form {
  padding: 20px;

  &-title {
    font-family: PingFang SC, PingFang SC;
    font-weight: 500;
    font-size: 16px;
    color: #191919;
    font-style: normal;
    text-transform: none;
  }

  &-item {
    margin-top: 20px;
  }

  &-label {
    min-width: 36%;
    font-weight: normal;
    font-family: PingFang SC, PingFang SC;
    font-size: 14px;
  }

  .tip-icon {
    font-size: 14px;
    color: #666;
    margin-left: 4px;
  }

  .question-guide {
    margin-top: 8px;
    &-left {
      margin-right: 10px;
      cursor: move;
    }
  }
  .btn-add{
    color: #3067EF;
  }

  :deep(.el-slider__input){
    width: 130px;
    margin-left: 30px;
  }

  :deep(.el-slider__bar) {
    height: 6px;
    background-color: #5E8BFB;
  }

  :deep(.el-slider__runway) {
    background: #E8E8E8;
    height: 6px;
  }

  :deep(.el-slider__button.hover){
    border: 4px solid #3067EF;
    transform: scale(1.3);
  }
  :deep(.el-input__wrapper.is-focus){
    box-shadow: 0 0 0 1px var(--el-input-border-color, var(--el-border-color)) inset;
  }
 
}
</style>