<template>
	<div class="dialogue-panel">
		<div class="dp_messageList" ref="messageListRef">
			<div class="dp_ml_item" v-for="item in messageList" :key="item.id">
				<div class="dp_ml_i_message right" v-if="item.userContent"><!--v-if="item.userContent"-->
          <div class="dp_ml_i_m_msgArea">
            <div class="dp_ml_i_m_ma_name" v-if="item.userName" v-text="item.userName"></div>
            <div class="dp_ml_i_m_ma_textBlok">
              <span v-html="item.userContent"></span>
            </div>
          </div>
          <div class="dp_ml_i_m_avatarArea">
            <div>
              <img src="../../../assets/img/avatar.png" alt="">
            </div>
          </div>
        </div>
        <div class="dp_ml_i_message left" v-if="item.aiContent || item.loading"><!--v-if="item.aiContent || item.loading"-->
          <div class="dp_ml_i_m_avatarArea">
            <div>
              <img src="../../../assets/img/ai_agent_header2.png" alt="">
            </div>
          </div>
          <div class="dp_ml_i_m_msgArea">
            <div class="dp_ml_i_m_ma_name" v-if="item.aiName" v-text="item.aiName"></div>
            <div class="dp_ml_i_m_ma_textBlok">
              <span v-if="item.aiContent" v-html="htmlContent(item.aiContent)"></span>
              <svg v-else xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><!-- Icon from SVG Spinners by Utkarsh Verma - https://github.com/n3r4zzurr0/svg-spinners/blob/main/LICENSE --><circle cx="4" cy="12" r="3" fill="currentColor"><animate id="svgSpinners3DotsBounce0" attributeName="cy" begin="0;svgSpinners3DotsBounce1.end+0.25s" calcMode="spline" dur="0.6s" keySplines=".33,.66,.66,1;.33,0,.66,.33" values="12;6;12"/></circle><circle cx="12" cy="12" r="3" fill="currentColor"><animate attributeName="cy" begin="svgSpinners3DotsBounce0.begin+0.1s" calcMode="spline" dur="0.6s" keySplines=".33,.66,.66,1;.33,0,.66,.33" values="12;6;12"/></circle><circle cx="20" cy="12" r="3" fill="currentColor"><animate id="svgSpinners3DotsBounce1" attributeName="cy" begin="svgSpinners3DotsBounce0.begin+0.2s" calcMode="spline" dur="0.6s" keySplines=".33,.66,.66,1;.33,0,.66,.33" values="12;6;12"/></circle></svg>
            </div>
          </div>
        </div>
			</div>
		</div>
		<!-- 清空聊天记录按钮区域 -->
		<div class="dp_clearArea">
			<div class="dp_clear_btn" 
					v-if="!sendMessageLoading && !dialogueLoading"
					@click.stop="openClearConfirm"
					:title="lang.ssClearChat">
				  <svg
              width="20"
              height="20"
              viewBox="0 0 20 20"
              fill="none"
              xmlns="http://www.w3.org/2000/svg"
            >
              <path
                fill-rule="evenodd"
                clip-rule="evenodd"
                d="M2.5 3.125C2.5 2.77982 2.77982 2.5 3.125 2.5H16.875C17.2202 2.5 17.5 2.77982 17.5 3.125V8.02715C17.5 8.37233 17.2202 8.65215 16.875 8.65215C16.5298 8.65215 16.25 8.37233 16.25 8.02715V3.75H3.75V16.25H8.125C8.47018 16.25 8.75 16.5298 8.75 16.875C8.75 17.2202 8.47018 17.5 8.125 17.5H3.125C2.77982 17.5 2.5 17.2202 2.5 16.875V3.125Z"
                fill="black"
                fill-opacity="0.6"
              />
              <path
                fill-rule="evenodd"
                clip-rule="evenodd"
                d="M5.625 6.1521C5.625 5.80692 5.90482 5.5271 6.25 5.5271H13.125C13.4702 5.5271 13.75 5.80692 13.75 6.1521C13.75 6.49728 13.4702 6.7771 13.125 6.7771H6.25C5.90482 6.7771 5.625 6.49728 5.625 6.1521Z"
                fill="black"
                fill-opacity="0.6"
              />
              <path
                fill-rule="evenodd"
                clip-rule="evenodd"
                d="M5.625 9.2771C5.625 8.93192 5.90482 8.6521 6.25 8.6521H9.37496C9.72014 8.6521 9.99996 8.93192 9.99996 9.2771C9.99996 9.62228 9.72014 9.9021 9.37496 9.9021H6.25C5.90482 9.9021 5.625 9.62228 5.625 9.2771Z"
                fill="black"
                fill-opacity="0.6"
              />
              <path
                fill-rule="evenodd"
                clip-rule="evenodd"
                d="M12.465 11.507L15.9141 14.9048C16.1279 14.5365 16.25 14.1088 16.25 13.6521C16.25 12.2714 15.1307 11.1521 13.75 11.1521C13.2799 11.1521 12.8406 11.2815 12.465 11.507ZM15.0374 15.7957L11.5873 12.397C11.3726 12.7659 11.25 13.1944 11.25 13.6521C11.25 15.0328 12.3693 16.1521 13.75 16.1521C14.2211 16.1521 14.6613 16.0222 15.0374 15.7957ZM11.0797 11.0192C11.759 10.3303 12.7051 9.9021 13.75 9.9021C15.8211 9.9021 17.5 11.581 17.5 13.6521C17.5 14.6767 17.0882 15.6064 16.4226 16.2827C15.7431 16.9729 14.7961 17.4021 13.75 17.4021C11.6789 17.4021 10 15.7232 10 13.6521C10 12.6263 10.4127 11.6957 11.0797 11.0192Z"
                fill="black"
                fill-opacity="0.6"
              />
            </svg>
			</div>
		</div>
		<div class="dp_inputArea">
			<div class="dp_ia_bottom">
				<div class="dp_ia_b_left">
					<div>
						<textarea
							v-model="inputText"
							type="text"
							:placeholder="lang.ssChatPhInput"
							@keydown.enter.exact.prevent="sendMessage"
						></textarea>
					</div>
				</div>
				<div class="dp_ia_b_right">
					<!-- 清空聊天记录按钮 -->
					<div
						class="dp_ia_b_r_btn"
						v-if="!sendMessageLoading"
						@click.stop="sendMessage"
					>
						<svg
							t="1756432184712"
							class="icon"
							viewBox="0 0 1024 1024"
							version="1.1"
							xmlns="http://www.w3.org/2000/svg"
							p-id="7156"
							width="200"
							height="200"
						>
							<path
								d="M211.649242 813.217191a425.984 425.984 0 1 0 602.421836-602.442865 425.984 425.984 0 1 0-602.421836 602.442865Z"
								fill="#00A0E9"
								p-id="7157"
							></path>
							<path
								d="M266.3936 427.7248l422.5024-103.5776c20.4288-5.0176 37.5296 15.9744 28.4672 34.9696l-188.2112 395.1616c-9.728 20.3776-39.3728 18.432-46.2848-3.072l-48.0256-149.4016a25.06752 25.06752 0 0 1 5.2224-24.3712L522.1888 486.4c5.0176-5.5808-1.6896-13.9264-8.192-10.0864l-108.9024 63.5392a24.9856 24.9856 0 0 1-24.6272 0.3072L260.2496 473.8048c-19.8656-10.9568-15.9232-40.6528 6.144-46.08z"
								fill="#FFFFFF"
								p-id="7158"
							></path>
						</svg>
					</div>
					<div
						class="dp_ia_b_r_btn"
						v-if="sendMessageLoading"
						@click.stop="stopSendMessage"
					>
						<svg
							t="1756432604950"
							class="icon"
							viewBox="0 0 1024 1024"
							version="1.1"
							xmlns="http://www.w3.org/2000/svg"
							p-id="11335"
							width="200"
							height="200"
						>
							<path
								d="M512 960C264.57 960 64 759.43 64 512S264.57 64 512 64s448 200.57 448 448-200.57 448-448 448z m0.43-83.66c201.01 0 364.01-163.01 364.01-364.01s-163-364.02-364.01-364.02-364.01 163.01-364.01 364.01 162.9 364.02 364.01 364.02zM371.99 343.92h280.03c15.44 0 27.96 12.52 27.96 27.96v280.13c0 15.44-12.52 27.96-27.96 27.96H371.99c-15.44 0-27.96-12.52-27.96-27.96V371.99c0-15.55 12.52-28.07 27.96-28.07z"
								p-id="11336"
								fill="#707070"
							></path>
						</svg>
					</div>
				</div>
			</div>
		</div>
    <div class="dialogueLoading" v-if="dialogueLoading">
      <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z" opacity=".25"/><path fill="currentColor" d="M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z"><animateTransform attributeName="transform" dur="0.75s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12"/></path></svg>
    </div>

    <!-- 清空聊天记录确认弹窗 -->
    <Modal
      :visible="clearConfirmVisible"
      :width="420"
      :closeButton="true"
      :closeOnClickMask="false"
      :closeOnEsc="false"
      @update:visible="val => clearConfirmVisible = val"
    >
      <div class="clear-confirm">
        <div class="clear-confirm__title">{{ lang.ssClearChat }}</div>
        <div class="clear-confirm__content">
          {{ lang.ssClearChatTip }}
        </div>
        <div class="clear-confirm__footer">
          <Button type="default" @click="clearConfirmVisible = false">{{ lang.ssCancel }}</Button>
          <Button type="primary" @click="handleConfirmClear">{{ lang.ssConfirmClear }}</Button>
        </div>
      </div>
    </Modal>
	</div>
</template>

<script lang="ts" setup>
import { ref, reactive, onMounted, computed } from 'vue'

import { fetchEventSource } from '@microsoft/fetch-event-source'
import MarkdownIt from 'markdown-it'
import api from '../../../services/course'
import message from '@/utils/message'
import Modal from '@/components/Modal.vue'
import Button from '@/components/Button.vue'
import { lang } from '@/main'



interface Props {
  courseid?: string | null
  userid?: string | null
}

const props = withDefaults(defineProps<Props>(), {
  courseid: null,
  userid: null,
})

interface Message {
	id: string;
	userContent: string;
	aiContent: string;
	createTime: string;
	userName: string;
	aiName: string;
	loading: boolean;
}

// 对话消息列表
const messageList = reactive<Message[]>([
  {
    id: '1',
    userContent: '',
    aiContent: lang.ssAiHello,
    createTime: new Date().toLocaleString().replace(/\//g, '-'),
    userName: lang.ssTeacher,
    aiName: lang.ssAiHelper,
    loading: false,
  },
])

// 发送消息loading
const sendMessageLoading = ref<boolean>(false)

// 整个对话加载loading
const dialogueLoading = ref<boolean>(false)

// 输入框文本
const inputText = ref('')

// 消息区域Ref
const messageListRef = ref<HTMLDivElement>()

// 发送消息请求实例
const curRequestController = ref<AbortController | null>(null)

// 用户名称
const userName = ref<string>('')

// 代理配置 / 会话信息
const agentData = ref<any>({})

// 清空聊天记录二次确认弹窗
const clearConfirmVisible = ref(false)

const htmlContent = computed(() => {
  const md = new MarkdownIt()
  return (_md:string) => {
    return md.render(_md)
  }
})


// 发送消息
const sendMessage = () => {
  if (sendMessageLoading.value) return
  if (!inputText.value.trim()) return
  const userInput = inputText.value.trim()
  inputText.value = ''
  sendMessageLoading.value = true
  const _uid = new Date().getTime().toString()
  const newMessage = {
    id: _uid,
    userContent: userInput,
    aiContent: '',
    createTime: new Date().toLocaleString().replace(/\//g, '-'),
    userName: userName.value || lang.ssTeacher,
    aiName: lang.ssAiHelper,
    loading: true,
  }
  messageList.push(newMessage)
  messageListScrollBottom()

  // const params = {
  //   model: 'gpt-4o-2024-11-20',
  //   temperature: 0,
  //   max_tokens: 4096,
  //   top_p: 1,
  //   frequency_penalty: 0,
  //   presence_penalty: 0,
  //   messages: [{ role: 'user', content: userInput}],
  //   uid: new Date().getTime().toString(),
  //   mind_map_question: '',
  //   stream: true,
  // }

  const params = {
    id: '978252d7-a26e-4e70-8d75-3336497abac1',
    message: userInput,
    userId: props.userid,
    // model: node.properties.item.modelType,
    model: 'open-gpt-4.1',
    file_ids: [],
    sound_url: '',
    temperature: 0.2,
    top_p: 1,
    max_completion_tokens: 4096,
    stream: true,
    uid: _uid,
    session_name: `${props.userid}_${props.courseid}_pptCourse`,
  }

  let _addText = ''
  curRequestController.value = new AbortController()

  fetchEventSource(
    'https://appapi.cocorobo.cn/api/agentchats/ai_agent_chat',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(params),
      signal: curRequestController.value.signal,
      onmessage(ev) {
        const _data = JSON.parse(ev.data).content
        if (_data === '[DONE]') {
          insertChat(_uid)
          return (sendMessageLoading.value = false)
        }
        _addText += _data
        const msgItem = messageList.find((item) => item.id === _uid)
        
        if (msgItem) {
          msgItem.aiContent = _addText
          msgItem.loading = false
        }
        messageListScrollBottom()
      },
      onclose() {
        sendMessageLoading.value = false
        curRequestController.value = null
        console.log('连接关闭')
      },
      onerror(err) {
        console.log(err)
        sendMessageLoading.value = false
        const errorMsgItem = messageList.find((item) => item.id === _uid)
        if (errorMsgItem) {
          errorMsgItem.aiContent = lang.ssNetErrShort
        }
      },
    }
  )

  // 发送消息
}

const stopSendMessage = () => {
  sendMessageLoading.value = false
  curRequestController.value?.abort()
  if (messageList.length > 0) {
    insertChat(messageList[messageList.length - 1].id)
  }
  console.log('主动关闭连接')
}

// 消息区域触底
const messageListScrollBottom = () => {
  if (messageListRef.value) messageListRef.value.scrollTop = messageListRef.value.scrollHeight
}

// 保存消息
const insertChat = async (uid: string) => {
  const _msg = messageList.find(i => i.id === uid)
  if ( props.userid && props.courseid && _msg) {
    const params = {
      userId: props.userid,
      userName: userName.value
        ? userName.value
        : await getUserName(props.userid),
      groupId: `${props.courseid?.slice(0, 31)}${props.userid?.slice(0, 5)}`,
      answer: _msg.aiContent,
      problem: _msg.userContent,
      file_id: '',
      alltext: _msg.aiContent,
      type: 'chat',
      filename: '',
      session_name: `${props.userid}_${props.courseid}_pptCourse`,
    }

    api.insertChat(params)
  }
}

// 获取用户名称
const getUserName = (uid:string | null) => {
  if (!uid) return '-'
  return new Promise(resolve => {
    return api.getUser(uid).then((res: any) => {
      const data = res[0][0]
      userName.value = data.username
      resolve(data.username)
    })
  })
}

// 获取对话内容
const getMessageList = () => {
  if (props.courseid && props.userid) {
    dialogueLoading.value = true
    const params = {
      userid: props.userid,
      groupid: `${props.courseid?.slice(0, 31)}${props.userid?.slice(0, 5)}`,
      session_name: `${props.userid}_${props.courseid}_pptCourse`,
    }
    api.getChatList(params).then((res: any) => {
      const data = JSON.parse(res.FunctionResponse).response
      if (data && data.length > 0) {
        data.forEach((item:any) => {
          const oldMessage = {
            id: item.id,
            userContent: item.problem,
            aiContent: item.answer,
            createTime: item.createtime,
            userName: userName.value || lang.ssTeacher,
            aiName: lang.ssAiHelper,
            loading: false,
          }
          messageList.push(oldMessage)
        })
      }
      dialogueLoading.value = false
    }).catch(() => {
      dialogueLoading.value = false
    })
  }
}

// 打开清空聊天记录确认弹窗
const openClearConfirm = () => {
  if (dialogueLoading.value) return
  clearConfirmVisible.value = true
}

// 实际执行清空聊天记录
const clearChatHistory = async () => {
  if (dialogueLoading.value) return
  console.log(agentData.value)

  dialogueLoading.value = true

  try {
    const params = {
      model: 'open-gpt-4.1',
      thread_id: agentData.value.thread_id,
      groupid: `${props.courseid?.slice(0, 31)}${props.userid?.slice(0, 5)}`,
      userid: props.userid,
    }

    const response = await api.clearDialogue(params)

    if (response) {
      // 清空本地消息列表，只保留初始欢迎消息
      messageList.splice(1) // 保留第一个欢迎消息

      // 重置消息列表为初始状态
      messageList[0] = {
        id: '1',
        userContent: '',
        aiContent: lang.ssAiHello,
        createTime: new Date().toLocaleString().replace(/\//g, '-'),
        userName: lang.ssTeacher,
        aiName: lang.ssAiHelper,
        loading: false,
      }

      console.log('聊天记录清空成功')
      message.success(lang.ssChatCleared)
    }
    else {
      throw new Error(`HTTP error! status: ${response.status}`)
    }
  }
  catch (error) {
    console.error('清空聊天记录失败:', error)
    message.error(lang.ssClearFail)
  }
  finally {
    dialogueLoading.value = false
  }
}

// 确认弹窗中点击“确认清空”
const handleConfirmClear = async () => {
  clearConfirmVisible.value = false
  await clearChatHistory()
}

const getAgentData = () => {
  dialogueLoading.value = true
  api.getAgentData({
    id: '978252d7-a26e-4e70-8d75-3336497abac1',
  }).then((res: any) => {
    console.log(res)
    agentData.value = {source: 'agent', ...res}
    getMessageList()
  })
}

onMounted(() => {
  getUserName(props.userid)
  
  getAgentData()
})

</script>

<style lang="scss" scoped>
.dialogue-panel {
	width: 100%;
	height: 100%;
	display: flex;
	flex-direction: column;
  position: relative;
  padding: 0 8px;
  box-sizing: border-box;
	.dp_messageList {
		width: 100%;
		height: calc(100% - 60px - 40px - 10px); // 减去输入框和清空按钮的高度
    overflow: auto;
		.dp_ml_item{
      width: 100%;
      height: auto;
      .dp_ml_i_message{
        width: 100%;
        height: auto;
        display: flex;
        margin-bottom: 20px;
        .dp_ml_i_m_avatarArea{
          width: 50px;
          height: auto;
          display: flex;
          justify-content: center;
          div{
            width: 40px;
            height: 40px;
            margin-top: 10px;
            border-radius: 50%;
            overflow: hidden;
            img{
              width: 100%;
              height: 100%;
              object-fit: cover;
            }
          }
        }
        .dp_ml_i_m_msgArea{
          width: calc(100% - 50px - 10px);
          height: auto;
          margin: 0 5px;
          margin-top: 5px;
          display: flex;
          flex-direction: column;
          .dp_ml_i_m_ma_name{
            max-width: 100%;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            font-size: 14px;
            color: #333;
            font-weight: 500;
            margin-bottom: 5px;
          }
          .dp_ml_i_m_ma_textBlok{
            width: fit-content;
            display: block;
            background-color: #F8F9FA;
            padding: 10px;
            border: solid 1px #E9ECEF;
            border-radius: 4px;
            &>svg{
              width: 17px;
              height: 17px;
            }
          }
        }
      }
    }
    .right{
      justify-content: flex-end;
      .dp_ml_i_m_msgArea{
        align-items: flex-end;
        .dp_ml_i_m_ma_name{
          text-align: right;
        }
        .dp_ml_i_m_ma_textBlok{
          background-color: #3681FC !important;
          color: #fff;
          border-color: #69A1FD !important;
        }
      }
      
    }
	}
	.dp_inputArea {
		width: 100%;
		height: 60px;
		.dp_ia_bottom {
			width: 100%;
			height: 100%;
			display: flex;
			align-items: center;
			.dp_ia_b_left {
				width: calc(100% - 50px);
				height: 100%;
				display: flex;
				align-items: center;
				justify-content: center;
				& > div {
					width: 100%;
					height: auto;
					display: flex;
					align-items: flex-end;
					border: solid 1px #ececec;
					border-radius: 6px;
					box-sizing: border-box;
					box-shadow: 0 0 10px #ececec;
					& > textarea {
						border: none;
						outline: none;
						width: 100%;
						height: 40px;
						background: none;
						text-indent: 0.5em;
						font-size: 14px;
						resize: none;
						box-sizing: border-box;
						padding: 10px 0;
						&::placeholder {
							color: #949494;
						}
					}
				}
			}
			.dp_ia_b_right {
				width: 45px;
				height: 100%;
				display: flex;
				align-items: center;
				justify-content: center;
				margin-left: 5px;
				.dp_ia_b_r_btn {
					width: 40px;
					height: 40px;
					border-radius: 50%;
					cursor: pointer;
					& > svg {
						width: 40px;
						height: 40px;
					}
				}
			}
		}
	}
  .dialogueLoading {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(255, 255, 255, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
  }
}

// 清空按钮区域样式
.dp_clearArea {
    width: 100%;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    padding: 0;
    border-bottom: 1px solid #f0f0f0;
    
    .dp_clear_btn {
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 5px;
        border: .5px solid #e0eafb;
        border-radius: 6px;
        background-color: #fff;
        color: #fff;
        cursor: pointer;
        transition: all 0.3s ease;
        font-size: 14px;
        
        &:hover {
            transform: translateY(-1px);
        }
        
        .icon {
            width: 20px;
            height: 20px;
            flex-shrink: 0;
        }
        
        .loading-icon {
            animation: spin 1s linear infinite;
        }
        
        .clear-text {
            font-weight: 500;
            white-space: nowrap;
        }
    }
}

// 清空按钮样式
.clear-btn {
  margin-right: 8px;
  background-color: #fff;
  border: 1px solid #ff4d4f;
  transition: all 0.3s ease;
  
  &:hover {
    background-color: #ff4d4f;
    transform: scale(1.05);
    
    .icon {
      fill: #fff;
    }
  }
  
  .loading-icon {
    animation: spin 1s linear infinite;
  }
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
</style>