<script>
export default {
  name: 'hitTest',
  data() {
    return {
      paramsConfig: {
        visible: false,
        searchMode: 'vector', // 默认选择向量检索
        similarity: 0.6, // 默认相似度
        topK: 5 // 默认引用分段数
      },
      inputMessage: '',
      loading: false,
      messages: [
        {
          id: 1,
          type: 'question',
          content: '黄金运用方式有哪些?',
          time: new Date()
        },
        {
          id: 2,
          type: 'answer',
          content: '根据您的问题，我找到了以下相关信息：',
          references: [
            {
              id: 1,
              title: '-',
              content:
                '黄金可以作为投资者的资产配置：（1）把黄金作为储备资产的投资者；（2）被保险人投资在黄金的抵押品或非标资产债券的担保；（3）或者是投资者的避险资产。',
              score: 0.709,
              file: '北京人寿的准备金（样表版）_有关项.pdf'
            },
            {
              id: 2,
              title: '新增分说明一下',
              content: '保险责任',
              score: 0.705,
              file: 'Sheet1'
            },
            {
              id: 3,
              title: '北京人寿承诺服务各项指标',
              content:
                '第二代保人寿保险营业执照人及行政管理人天津后勤保障处；5.第三代保人寿保险公司承诺为公司客户方案服力及运营提供客户服务力；6...',
              score: 0.703,
              file: '北京人寿承诺服务各项指标（有效版）102026.pdf'
            },
            {
              id: 4,
              title: '-',
              content: '# 黄金的分：年金',
              score: 0.7,
              file: 'loma.md'
            },
            {
              id: 5,
              title: '第12讲年金 152',
              content: '一、年金基础 153',
              score: 0.698,
              file: 'loma.md'
            }
          ],
          time: new Date()
        }
      ]
    }
  },
  methods: {
    sendMessage() {
      if (!this.inputMessage.trim()) return

      // 添加用户问题到消息列表
      this.messages.push({
        id: this.messages.length + 1,
        type: 'question',
        content: this.inputMessage,
        time: new Date()
      })

      // 清空输入框
      this.inputMessage = ''

      // 模拟加载状态
      this.loading = true

      // 模拟API请求延迟
      setTimeout(() => {
        this.loading = false
        // 这里可以添加实际的API调用逻辑
      }, 1000)
    },
    getTableData() {
      // 根据之前的记忆，修复getTableData函数，确保正确返回Promise
      return this.$api
        .getDocByPage(this.queryParams)
        .then(res => {
          return res.data
        })
        .catch(err => {
          console.error('获取数据失败:', err)
          return []
        })
    },
    formatScore(score) {
      return score.toFixed(3)
    }
  }
}
</script>

<template>
  <div class="hit-test-container">
    <!-- 中间内容区域 -->
    <div class="content-area">
      <div class="empty-state" v-if="messages.length === 0">
        <el-image alt="当前会话尚无记录"></el-image>
        <p>这里会显示命中测试的记录</p>
      </div>
      <div class="messages" v-else>
        <div
          v-for="message in messages"
          :key="message.id"
          class="message-item"
          :class="message.type"
        >
          <!-- 问题消息 -->
          <div v-if="message.type === 'question'" class="question-message">
            <div class="message-header">
              <el-avatar size="small" icon="el-icon-user"></el-avatar>
              <div class="message-info">
                <div class="message-title">用户提问</div>
              </div>
            </div>
            <div class="message-content">{{ message.content }}</div>
          </div>

          <!-- 回答消息 -->
          <div v-else-if="message.type === 'answer'" class="answer-message">
            <div class="message-header">
              <el-avatar size="small" icon="el-icon-s-custom"></el-avatar>
              <div class="message-info">
                <div class="message-title">AI 回复</div>
              </div>
            </div>
            <div class="message-content">{{ message.content }}</div>

            <!-- 引用内容 -->
            <div
              class="references"
              v-if="message.references && message.references.length"
            >
              <div
                v-for="(ref, index) in message.references"
                :key="index"
                class="reference-item"
              >
                <div class="reference-header">
                  <div class="reference-index">{{ index + 1 }}</div>
                  <div class="reference-title">{{ ref.title }}</div>
                  <div class="reference-score">
                    {{ formatScore(ref.score) }}
                  </div>
                </div>
                <div class="reference-content">{{ ref.content }}</div>
                <div class="reference-footer">
                  <el-tag size="mini" type="info">
                    <i class="el-icon-document"></i> {{ ref.file }}
                  </el-tag>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 加载状态 -->
        <div v-if="loading" class="loading-message">
          <el-skeleton style="width: 100%" animated>
            <template slot="template">
              <el-skeleton-item
                variant="p"
                style="width: 100%; height: 60px;"
              />
              <el-skeleton-item variant="p" style="width: 90%; height: 20px;" />
              <el-skeleton-item variant="p" style="width: 80%; height: 20px;" />
            </template>
          </el-skeleton>
        </div>
      </div>
    </div>

    <!-- 底部输入框 -->
    <div class="footer">
      <!-- 参数内容 -->
      <el-popover placement="top" width="480" v-model="paramsConfig.visible">
        <div class="search-params-container">
          <h3>检索模式</h3>

          <el-radio-group
            v-model="paramsConfig.searchMode"
            class="search-mode-options"
          >
            <div
              class="search-mode-option"
              :class="{ active: paramsConfig.searchMode === 'vector' }"
            >
              <el-radio v-model="paramsConfig.searchMode" label="vector"
                >向量检索</el-radio
              >
              <p class="option-desc">
                向量检索是一种基于向量相似度的检索方式，适用于知识库中的大数据量场景。
              </p>
            </div>

            <div
              class="search-mode-option"
              :class="{ active: paramsConfig.searchMode === 'fulltext' }"
            >
              <el-radio v-model="paramsConfig.searchMode" label="fulltext"
                >全文检索</el-radio
              >
              <p class="option-desc">
                全文检索是一种基于文本相似度的检索方式，适用于知识库中的小数据量场景。
              </p>
            </div>

            <div
              class="search-mode-option"
              :class="{ active: paramsConfig.searchMode === 'hybrid' }"
            >
              <el-radio v-model="paramsConfig.searchMode" label="hybrid"
                >混合检索</el-radio
              >
              <p class="option-desc">
                混合检索是一种基于向量和文本相似度的检索方式，适用于知识库中的中等数据量场景。
              </p>
            </div>
          </el-radio-group>

          <div class="params-settings">
            <div class="param-item">
              <span class="param-label">相似度高于</span>
              <el-input-number
                v-model="paramsConfig.similarity"
                :precision="3"
                :step="0.001"
                :min="0"
                :max="1"
                size="small"
                controls-position="right"
              ></el-input-number>
            </div>

            <div class="param-item">
              <span class="param-label">引用分段数 TOP</span>
              <el-input-number
                v-model="paramsConfig.topK"
                :min="1"
                :max="20"
                size="small"
                controls-position="right"
              ></el-input-number>
            </div>
          </div>

          <div class="action-buttons">
            <el-button size="small" @click="paramsConfig.visible = false"
              >取消</el-button
            >
            <el-button
              type="primary"
              size="small"
              @click="paramsConfig.visible = false"
              >确定</el-button
            >
          </div>
        </div>
        <el-button icon="el-icon-setting" size="small" slot="reference"
          >参数设置</el-button
        >
      </el-popover>

      <el-input
        v-model="inputMessage"
        placeholder="请输入"
        class="message-input"
        @keyup.enter.native="sendMessage"
      >
        <template slot="append">
          <el-button
            icon="el-icon-s-promotion"
            @click="sendMessage"
            size="small"
          ></el-button>
        </template>
      </el-input>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.hit-test-container {
  display: flex;
  flex-direction: column;
  height: 86vh;
  background-color: #f5f7fa;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  overflow: hidden;

  .header {
    padding: 10px 20px;
    border-bottom: 1px solid #e4e7ed;
    background-color: #fff;
  }

  .content-area {
    flex: 1;
    overflow-y: auto;
    padding: 20px;
    display: flex;
    flex-direction: column;

    .empty-state {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      height: 100%;
      color: #909399;

      .el-image {
        width: 120px;
        margin-bottom: 20px;
      }
    }

    .messages {
      display: flex;
      flex-direction: column;
      gap: 20px;

      .message-item {
        display: flex;
        flex-direction: column;

        &.question {
          align-items: flex-end;

          .question-message {
            background-color: #ecf5ff;
            border-radius: 8px 0 8px 8px;
            padding: 12px;
            max-width: 80%;

            .message-header {
              display: flex;
              align-items: center;
              margin-bottom: 8px;

              .message-info {
                margin-left: 8px;
              }

              .message-title {
                font-weight: 500;
                font-size: 14px;
                color: #409eff;
              }
            }

            .message-content {
              word-break: break-word;
            }
          }
        }

        &.answer {
          align-items: flex-start;

          .answer-message {
            background-color: #fff;
            border-radius: 0 8px 8px 8px;
            padding: 12px;
            max-width: 90%;
            box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);

            .message-header {
              display: flex;
              align-items: center;
              margin-bottom: 8px;

              .message-info {
                margin-left: 8px;
              }

              .message-title {
                font-weight: 500;
                font-size: 14px;
                color: #67c23a;
              }
            }

            .message-content {
              margin-bottom: 16px;
              word-break: break-word;
            }

            .references {
              display: flex;
              flex-direction: column;
              gap: 12px;

              .reference-item {
                border: 1px solid #ebeef5;
                border-radius: 4px;
                padding: 12px;
                background-color: #fafafa;

                .reference-header {
                  display: flex;
                  align-items: center;
                  margin-bottom: 8px;

                  .reference-index {
                    width: 24px;
                    height: 24px;
                    border-radius: 50%;
                    background-color: #409eff;
                    color: #fff;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    font-size: 12px;
                    margin-right: 8px;
                  }

                  .reference-title {
                    flex: 1;
                    font-weight: 500;
                  }

                  .reference-score {
                    color: #409eff;
                    font-weight: 500;
                  }
                }

                .reference-content {
                  margin-bottom: 8px;
                  font-size: 13px;
                  color: #606266;
                  line-height: 1.5;
                }

                .reference-footer {
                  display: flex;
                  justify-content: flex-start;
                }
              }
            }
          }
        }
      }

      .loading-message {
        padding: 12px;
        background-color: #fff;
        border-radius: 8px;
        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
        margin-top: 10px;
      }
    }
  }

  .footer {
    padding: 10px 20px;
    background-color: #fff;
    border-top: 1px solid #e4e7ed;
    display: flex;
    align-items: center;

    .el-popover__reference {
      margin-right: 10px;
    }

    .message-input {
      flex: 1;
    }
  }
}

// 参数设置弹窗样式
.search-params-container {
  padding: 10px;

  h3 {
    margin-top: 0;
    margin-bottom: 15px;
    font-size: 16px;
    font-weight: 500;
  }

  .search-mode-options {
    margin-bottom: 20px;

    .search-mode-option {
      padding: 10px;
      border: 1px solid #e4e7ed;
      border-radius: 4px;
      margin-bottom: 10px;

      &.active {
        border-color: #409eff;
        background-color: #ecf5ff;
      }

      .option-desc {
        margin: 5px 0 0 24px;
        font-size: 12px;
        color: #909399;
        line-height: 1.4;
      }
    }
  }

  .params-settings {
    display: flex;
    justify-content: space-between;
    margin-bottom: 20px;

    .param-item {
      display: flex;
      align-items: center;

      .param-label {
        margin-right: 10px;
        white-space: nowrap;
      }
    }
  }

  .action-buttons {
    display: flex;
    justify-content: flex-end;

    .el-button {
      margin-left: 10px;
    }
  }
}
</style>
