<template>
  <div class="ai-consultation-outer">
    <div class="ai-consultation-container">
      <div class="chat-area">
        <!-- 对话区域 -->
        <div class="dialog-area">
          <div
            v-for="(message, index) in dialogMessages"
            :key="index"
            :class="['dialog-message', message.type]"
          >
            <div class="message-text" v-html="renderMd(message.content)" />
            <span v-if="message.type === 'ai' && isAiStreaming && index === dialogMessages.length - 1" class="typing-cursor">▍</span>
          </div>
        </div>
      </div>

      <div class="bottom-input-wrapper">
        <div class="input-container">
          <a-textarea
            ref="consultTextarea"
            v-model="doctorInputText"
            placeholder="医生补充信息或提问..."
            class="bottom-input"
            :rows="1"
            resize="none"
            @input="handleInput"
            @keydown="handleKeydown"
          ></a-textarea>

          <div class="input-controls-right">
            <span class="enter-tip">Enter 发送 · Shift+Enter 换行</span>
            <a-button
              type="primary"
              shape="circle"
              class="send-btn"
              @click="handleSendMessage"
              :disabled="!doctorInputText.trim()"
            >
              <span class="send-icon">↑</span>
            </a-button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { startEventStreamPOST } from '@vue2-client/services/api/restTools'
import { marked } from 'marked'
import moment from 'moment/moment'
import { mapState } from 'vuex'

export default {
  name: 'AIConsultation',
  data() {
    return {
      currentDialogId: null,
      doctorInputText: '',
      isPlaying: false,
      isRecording: false,
      patientComplaint: '',
      doctorQuestions: [],
      examinationOrder: null,
      aiDiagnosis: null,
      dialogMessages: [],
      currentStreamConnection: null,
      isAiStreaming: false,
      resizeTimeout: null
    }
  },
  computed: {
    ...mapState('account', {currUser: 'user'})
  },
  mounted() {
    this.$nextTick(() => {
      this.autoResizeTextarea()
    })
  },
  beforeDestroy() {
    // 组件销毁时关闭流式连接
    if (this.currentStreamConnection) {
      this.currentStreamConnection()
      this.currentStreamConnection = null
    }
    if (this.resizeTimeout) {
      clearTimeout(this.resizeTimeout)
    }
  },
  methods: {
    autoResizeTextarea() {
      this.$nextTick(() => {
        const textarea = this.$refs.consultTextarea?.$el || this.$refs.consultTextarea
        if (!textarea) return

        textarea.style.height = 'auto'
        const scrollHeight = textarea.scrollHeight
        textarea.style.height = `${Math.min(Math.max(scrollHeight, 120), 250)}px`
      })
    },

    handleInput() {
      if (this.resizeTimeout) clearTimeout(this.resizeTimeout)
      this.resizeTimeout = setTimeout(() => {
        this.autoResizeTextarea()
      }, 16)
    },

    renderMd(text) {
      if (!text) return ''
      try {
        return marked.parse(text, { breaks: true, gfm: true, headerIds: false, mangle: false })
      } catch {
        return text
      }
    },

    handleKeydown(event) {
      if (event.key === 'Enter' && !event.shiftKey) {
        event.preventDefault()
        this.handleSendMessage()
      }
    },

    initDialog() {
      if (!this.currentDialogId) {
        this.currentDialogId = moment().format('YYYYMMDDHHmmss')
      }
    },

    clearDialog() {
      this.currentDialogId = moment().format('YYYYMMDDHHmmss')
      this.dialogMessages = []
    },

    handleSendMessage() {
      if (!this.doctorInputText.trim()) return

      // 确保有dialogId
      if (!this.currentDialogId) {
        this.initDialog()
      }

      const messageContent = this.doctorInputText.trim()
      const doctorMessage = {
        type: 'user',
        content: messageContent,
        time: new Date().toLocaleTimeString(),
        timestamp: Date.now()
      }
      this.dialogMessages.push(doctorMessage)
      this.scrollToBottom()

      this.doctorInputText = ''
      this.autoResizeTextarea()

      const chatId = this.currentDialogId
      let aiContent = ''
      const aiMsgIndex = this.dialogMessages.length
      this.dialogMessages.push({
        type: 'ai',
        content: '',
        time: new Date().toLocaleTimeString(),
        timestamp: Date.now()
      })
      this.scrollToBottom()

      this.isAiStreaming = true

      this.currentStreamConnection = startEventStreamPOST(
        '/his-web/api/af-his/ai/chat/stream',
        { userMessage: messageContent, chatId, model: '', prompt: '', useContext: true, user: this.currUser.operInfo },
        {'Content-Type': 'application/json'},
        (data, type) => {
          if (type === 'additionalInfo' || type === 'sourceInfo') return

          let textChunk = ''
          if (typeof data === 'object' && data !== null) {
            const choices = data.choices
            if (Array.isArray(choices) && choices.length > 0) {
              const delta = choices[0].delta

              // 优先取 delta.content（标准 OpenAI 格式）
              if (delta && typeof delta.content === 'string' && delta.content) {
                textChunk = delta.content
              }

              // 兼容百川模型的 thinking 字段
              if (!textChunk && delta && delta.thinking) {
                const thinking = delta.thinking
                // 取 summary 描述
                if (thinking.summary && typeof thinking.summary === 'string') {
                  textChunk = `[思考中] ${thinking.summary}`
                }
                // 取 reasoning steps
                if (Array.isArray(thinking.steps)) {
                  const activeStep = thinking.steps.find(s => s.status === 'in_progress')
                  if (activeStep && activeStep.label) {
                    textChunk = `[思考中] ${activeStep.label}`
                  }
                }
              }

              // 检测模型拒答
              const finishReason = choices[0].finish_reason
              if (finishReason === 'refuse_answer') {
                const refuseTip = '\n\n> ⚠️ 很抱歉，当前问题我无法回答，请尝试调整提问方式或联系管理员。'
                if (!this.dialogMessages[aiMsgIndex].content.includes('无法回答')) {
                  this.dialogMessages[aiMsgIndex].content += refuseTip
                  this.isAiStreaming = false
                  this.scrollToBottom()
                }
              }
            }
          } else if (typeof data === 'string') {
            textChunk = data
          }

          if (textChunk) {
            aiContent += textChunk
            this.dialogMessages[aiMsgIndex].content = aiContent
            this.scrollToBottom()
          }
        },
        (error) => {
          this.isAiStreaming = false
          this.dialogMessages[aiMsgIndex].content += `\n\n[错误: ${error.message || '请求失败'}]`
          this.scrollToBottom()
        },
        () => {
          this.isAiStreaming = false
          this.scrollToBottom()
        }
      )
    },

    setPatientComplaint(complaint) {
      this.patientComplaint = complaint
    },

    scrollToBottom(delay = 0) {
      this.$nextTick(() => {
        setTimeout(() => {
          const chatArea = document.querySelector('.chat-area')
          if (chatArea) {
            chatArea.scrollTop = chatArea.scrollHeight
          }
        }, delay)
      })
    },

    reset() {
      if (this.currentStreamConnection) {
        this.currentStreamConnection()
        this.currentStreamConnection = null
      }
      this.isAiStreaming = false
      this.patientComplaint = ''
      this.doctorQuestions = []
      this.examinationOrder = null
      this.aiDiagnosis = null
      this.doctorInputText = ''
      this.isPlaying = false
      this.isRecording = false
      this.dialogMessages = []
      this.$nextTick(() => {
        this.autoResizeTextarea()
        const chatArea = document.querySelector('.chat-area')
        if (chatArea) {
          chatArea.scrollTop = 0
        }
      })
    }
  }
}
</script>

<style scoped>
.ai-consultation-outer {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  width: 100%;
  height: 860px;
}

.ai-consultation-container {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  background: #FFFFFF;
  border: 1px solid #E5E9F0;
}

.chat-area {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
  background: #fff;
  min-height: 690px;
}

.dialog-area {
  display: flex;
  flex-direction: column;
}

/* 底部输入框区域 */
.bottom-input-wrapper {
  flex-shrink: 0;
  padding: 12px 16px;
  background: #fff;
  border-top: 1px solid #E5E9F0;
}

.input-container {
  position: relative;
  width: 100%;
}

.bottom-input {
  width: 100%;
  min-height: 52px;
  border: 1px solid #E5E9F0;
  border-radius: 4px;
  padding: 12px 60px 12px 16px;
  font-family: 'Source Han Sans', 'Microsoft YaHei', sans-serif;
  font-size: 16px;
  color: #313131;
  resize: none;
  outline: none;
  box-sizing: border-box;
}

.bottom-input:focus {
  border-color: #1890ff;
  box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}

.bottom-input::placeholder {
  color: #999;
}

.input-controls-right {
  position: absolute;
  right: 20px;
  bottom: 12px;
  display: flex;
  align-items: center;
  gap: 8px;
  z-index: 2;
}

.enter-tip {
  font-family: 'Inter', sans-serif;
  font-size: 14px;
  font-weight: 500;
  color: #9E9E9E;
  padding: 4px 8px;
}

.send-btn {
  width: 30px;
  height: 30px;
  background: #0057FE;
  border: none;
  border-radius: 50%;
  color: #fff;
  font-size: 14px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}

.send-btn:hover {
  background: #0040cc;
}

.send-icon {
  font-size: 14px;
  font-weight: bold;
}

/* 对话区域样式 */
.dialog-message {
  display: flex;
  margin-bottom: 16px;
  align-items: flex-start;
}

.dialog-message:last-child {
  margin-bottom: 0;
}

.dialog-message.ai {
  flex-direction: row;
}

.dialog-message.user {
  flex-direction: row-reverse;
}

.dialog-message.user .message-text {
  text-align: right;
}

.message-text {
  opacity: 1;
  font-family: Source Han Sans;
  font-size: 16px;
  font-weight: normal;
  line-height: normal;
  text-align: justify;
  letter-spacing: 0em;
  font-feature-settings: "kern" on;
  max-width: 100%;
  color: #313131;
}

.typing-cursor {
  display: inline-block;
  margin-left: 2px;
  color: #0057FE;
  font-size: 18px;
  animation: blink 1s step-end infinite;
}

@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}
</style>
