<template>
  <div id="app">
    <div class="main-container">
      <!-- 信息区 -->
      <div class="info-container">
        <!-- 返回按钮 -->
        <el-button class="back-button" type="text" @click="goBack">
          <el-icon><Back /></el-icon>
        </el-button>
        <h2 class="task-name">{{ aiSpeakingAssignmentInfo.assignmentName }}</h2>
        <div class="task-time">
          <div class="start-time">开始时间：{{ formatDate(aiSpeakingAssignmentInfo.startTime) }}</div>
          <div class="end-time">截止时间：{{ formatDate(aiSpeakingAssignmentInfo.endTime) }}</div>

        </div>
        <div class="data-item">
          <span class="data-label">作业描述</span>
          <div class="scrollable-description">
            {{ aiSpeakingAssignmentInfo.description !== null ? aiSpeakingAssignmentInfo.description : '未设置' }}
          </div>
        </div>
            <div class="data-item" v-if="aiSpeakingAssignmentInfo.descriptionFile">
              <span class="data-label">作业附件</span>
              <el-icon  @click="openEditor(aiSpeakingAssignmentInfo.descriptionFile, aiSpeakingAssignmentInfo.assignmentName)"><Document /></el-icon>
            </div>
            <div class="data-item">
              <span class="data-label">最短交流时间 </span>
              <span class="data-value">{{ aiSpeakingAssignmentInfo.minDuration !== null ? aiSpeakingAssignmentInfo.minDuration : '未设置' }} min</span>
            </div>
            <div class="data-item">
              <span class="data-label">最少交互次数 </span>
              <span class="data-value">{{ aiSpeakingAssignmentInfo.minInteraction !== null ? aiSpeakingAssignmentInfo.minInteraction : '未设置' }}</span>
            </div>
            <div class="data-item">
              <span class="data-label">累计交流时长 </span>
              <span class="data-value">{{ formatDuration(recordingDuration)  }}</span>
            </div>
            <!-- 作业操作按钮组 -->
        <div class="homework-button-group">
          <el-button @click="startHomework" class="start-homework-button">
            {{isHomeworkSubmitted ? "作业记录>" : (hasHomeworkSaved ? "继续作业" : "开始作业") }}
          </el-button>
          <el-button @click="saveHomework" class="save-homework-button" v-if="!isHomeworkSubmitted"
            >暂存作业</el-button
          >
          <el-button @click="resetHomework" class="reset-homework-button" v-if="!isHomeworkSubmitted"
            >重试作业</el-button
          >
          <el-button @click="submitHomework" class="submit-homework-button" v-if="!isHomeworkSubmitted"
            >提交作业</el-button
          >
        </div>
      </div>
      <!-- 问答区 -->
      <div class="chat-container-wrapper">
        <el-card class="chat-container">
          <template #header>
            <div class= "card-header-fixed">
            <div class="card-wrapper">
              <el-form-item label="voice:" style="margin-bottom: 0;">
                <el-select
                  v-model="voiceCode"
                  placeholder="选择语音类型"
                  style="margin-right: 20px; width: 120px"
                >
                  <el-option
                    v-for="voice in voiceOptions"
                    :key="voice.code"
                    :label="voice.name"
                    :value="voice.code"
                  >
                  <div style="display: flex; align-items: center;">
                    <el-avatar :src="voice.avatar || voiceOptions[0]?.avatar" size="small" style="margin-right: 10px;"></el-avatar>
                    <span>{{ voice.name }}</span>
                    <el-button
                      @click.stop="toggleAudio(voice)"
                      :icon="voice.isPlaying ? VideoPause : VideoPlay"
                      circle
                      size="small"
                      style="margin-left: 20px"
                    />
                  </div>
                  </el-option>
                </el-select>
                </el-form-item>
              <div class="card-header">口语对话区</div>
              <div class="status-label-wrapper">
                <span
                  :class="{
                    'status-default': !isHomeworkStarted,
                    'status-started':
                      isHomeworkStarted &&
                      !isHomeworkSaved &&
                      !isHomeworkSubmitted,
                    'status-saved': isHomeworkSaved && !isHomeworkSubmitted,
                    'status-submitted': isHomeworkSubmitted,
                  }"
                >
                  {{ getStatusText() }}
                </span>
              </div>
             </div>
            </div>
          </template>
          <div class="chat-messages" ref="chatContainerRef">
            <div
              v-for="(message, index) in chatMessages"
              :key="index"
              :class="{
                'user-message': message.sender === 'user',
                'ai-message': message.sender === 'ai',
              }"
            >
              <el-avatar
                :src="message.sender === 'user' ? userAvatar : getAvatar(message.voiceCode)"
                size="small"
                style="flex-shrink:0"
                shape="circle"
              ></el-avatar>
              <div class="message-content">
                <div class="message-text"  @click="handleMessageClick(message, index)">{{ message.text }}</div>
                <div class="message-time">{{ formatTimestamp(message.time) }}</div>
              </div>
               <!-- 添加播放图标 -->
              <el-button
                v-if="message.sender === 'ai'&& message.audioUrl"
                @click="playAudio(message)"
                :icon="message.isPlaying ? VideoPause : VideoPlay"
                circle
                size="default"
              ></el-button>
              <el-button
                v-if="message.sender === 'user' && message.audioUrl"
                @click="playAudio(message)"
                :icon="message.isPlaying ? VideoPause : VideoPlay"
                circle
                size="default"
              ></el-button>
            </div>
          </div>
        </el-card>
        <div class="input-container">
          <!-- 修改为语音输入框 -->
          <input
            v-model="userInput"
            placeholder="请点击语音开始按钮进行对话"
            @keyup.enter="sendMessage"
            x-webkit-speech
            speech
            :disabled="!isHomeworkStarted || isHomeworkSubmitted"
          />
          <el-button
            @click="startRecording"
            class="start-button"
            :disabled="!isHomeworkStarted || isHomeworkSubmitted || hasStartPlay || isLoading"
          >
            {{ hasStopRecording ? "继续" : "开始" }}
          </el-button>
          <el-button
            @click="stopRecording"
            class="stop-button"
            :disabled="!isHomeworkStarted || isHomeworkSubmitted || hasStartPlay || isLoading"
          >
            暂停
          </el-button>
          <el-button
            @click="resetRecording"
            class="reset-button"
            :disabled="!isHomeworkStarted || isHomeworkSubmitted || isLoading"
          >
            重试
          </el-button>
          <el-button
            @click="sendMessage"
            class="send-button"
            :disabled="!isHomeworkStarted || isHomeworkSubmitted || isLoading"
          >
            {{ isLoading ? "发送中..." : " 发送"}}
          </el-button>
        </div>
        <div class="recording-bar">
          <div class="recording-bar">
            <progress
              :value="playTime"
              :max="recorder && recorder.duration"
            ></progress>
            <p>
              {{ playTime.toFixed(2) }}/{{
                recorder && recorder.duration.toFixed(2)
              }}
            </p>
            <button
              class="wechat-audio-button"
              :disabled="!isHomeworkStarted || isHomeworkSubmitted || recorder.duration == 0"
              @click="togglePlayback"
            >
              <span
                class="icon"
                :class="{ play: !isPlaying, pause: isPlaying }"
              ></span>
              <span class="text">{{ isPlaying ? "暂停" : "播放" }}</span>
            </button>
          </div>
        </div>
      </div>
       <!-- 右侧语音分析模块 -->
     <VoiceAnalysis ref="voiceAnalysis" :userId = "userId" :assignmentId="assignmentId" :key="voiceInctanceKey"/>
     <video ref="cameraPreview" class="camera-preview" autoplay muted v-show="isHomeworkStarted"></video>
     <div class="recording-duration" v-if="isHomeworkStarted">
        录制时长: {{ formatDuration(recordingDuration) }}
      </div>
      <ViewsWordEditor v-if="aiSpeakingAssignmentInfo.descriptionFile" :alert="alertProps" :docxInfo="docxInfo"></ViewsWordEditor>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick, onBeforeUnmount, reactive, useId } from "vue";
import { ElMessage, ElLoading } from "element-plus";
import {useFormatDate} from "@/hooks/useFormatDate";
import doubaoApis from "@/apis/doubao";
import fileApis from "@/apis/file"
import aiSpeakingAssignmentApis from '@/apis/ai_speaking_assignment';
import mediaApis from "@/apis/media"
import engagementApis from "@/apis/engagement";
import Recorder from "js-audio-recorder";
import ViewsWordEditor from "@/components/ViewsWordEditor/ViewsWordEditor.vue";
import { VideoPlay, VideoPause,Back, Document} from '@element-plus/icons-vue';
import VoiceAnalysis from "./component/VoiceAnalysis.vue";
import { useRoute, useRouter } from 'vue-router';
import {useStore} from "@/store";
// 引入头像图片
import userAvatar from "@/assets/user.png";
import ryanAvatar from "@/assets/ryan.png"
import gavinAvatar from "@/assets/gavin.png"
import lauraAvatar from "@/assets/laura.png"
import ashleighAvatar from "@/assets/ashleigh.png"
import {useXfAsr} from "@/utils/xunfeiUtil";

const { startRecognition, stopRecognition, resultText } = useXfAsr();

const route = useRoute();
const router = useRouter();
const store = useStore();
const {formatDate} = useFormatDate()
const userId = Number(store.user.id);
const assignmentId = Number(route.params.assignmentId)
const voiceCode = ref(0);
const voiceOptions = ref([
  { code: 0, name: "Ryan", audioUrl:"https://eai-files.oss-cn-shanghai.aliyuncs.com/tts_1744024346.wav", isPlaying: false, avatar: ryanAvatar },
  { code: 1, name: "Gavin", audioUrl:"https://eai-files.oss-cn-shanghai.aliyuncs.com/tts_1744024442.wav",isPlaying:false, avatar:gavinAvatar },
  { code: 2, name: "Laura", audioUrl:"https://eai-files.oss-cn-shanghai.aliyuncs.com/tts_1744024469.wav", isPlaying:false, avatar:lauraAvatar },
  { code: 3, name: "Ashleigh", audioUrl:"https://eai-files.oss-cn-shanghai.aliyuncs.com/tts_1744024502.wav", isPlaying:false, avatar:ashleighAvatar },
]);
const isLoading = ref(false); // 加载状态
const aiSpeakingAssignmentInfo = ref({
    assignmentName: "",
    description: "",
    descriptionFile: '',
    type: "",
    startTime: "",
    endTime: "",
    minDuration:null,
    minInteraction:null,
    surveyLinks:[''],
    surveyDuration:null,
})

// 存储聊天消息的数组
const chatMessages = ref([]);
// 用户输入的问题
const userInput = ref("");

// 语音识别相关
let recognition = ref(null);
const isRecording = ref(false);
const recorder = ref(null)
const playTime = ref(0);
const timer = ref(null);
const recordSrc = ref(null);
const hasStopRecording = ref(null);
const isPlaying = ref(false);

let currentAudio = null; // 当前播放的音频对象
// 播放/暂停音频
const toggleAudio = (voice) => {
  // 如果当前有其他音频正在播放，则暂停
  if (currentAudio && currentAudio !== voice.audio) {
    currentAudio.pause();
    currentAudio.onended = null; // 移除之前的 onended 回调
    voiceOptions.value.forEach((v) => {
      if (v.audio === currentAudio) {
        v.isPlaying = false;
      }
    });
  }

  // 如果当前语音未初始化，则创建 Audio 对象
  if (!voice.audio) {
    voice.audio = new Audio(voice.audioUrl);
    voice.audio.onended = () => {
      voice.isPlaying = false;
      currentAudio = null;
    };
  }
  // 如果当前语音正在播放，则暂停
  if (voice.isPlaying) {
    voice.audio.pause();
    voice.isPlaying = false;
  } else {
    // 如果当前语音已暂停，则继续播放
    if (currentAudio === voice.audio && voice.audio.paused) {
      voice.audio.play();
    } else {
      // 否则，开始播放新语音
      voice.audio.play();
      currentAudio = voice.audio;
    }
    voice.isPlaying = true;
  }
};
const initRecognitionValue = ()=>{
  recognition.value = null;
  isRecording.value = false;
  recorder.value = new Recorder({
    sampleRate: 16000, // 采样率 16 kHz
    sampleBits: 16,    // 位长 16 bit
    numChannels: 1,    // 单声道
  })
  playTime.value = 0;
  timer.value = null;
  recordSrc.value = null;
  hasStopRecording.value = null;
  isPlaying.value = false;
  userInput.value = "";
}
// 作业状态
const isHomeworkStarted = ref(false);
const isHomeworkSaved = ref(false);
const isHomeworkSubmitted = ref(false);
const hasHomeworkSaved = ref(false);

// 摄像头录制相关
const mediaRecorder = ref(null);
const recordedChunks = ref([]);
// 暂存的录制数据
const savedChunks = ref([]);
const ffmpeg = ref(null);
// 初始化语音识别
// 初始化语音识别
const initRecognition = () => {
  const SpeechRecognition =
    window.SpeechRecognition || window.webkitSpeechRecognition;
  if (SpeechRecognition) {
    recognition.value = new SpeechRecognition();
    recognition.value.lang = "en-US";
    recognition.value.continuous = true;
    recognition.value.interimResults = true; // 实时获取识别结果
     // 语音识别开始事件
    recognition.value.onstart = () => {
      console.log("语音识别已启动");
    };

    // 语音识别结束事件
    recognition.value.onend = () => {
      console.log("语音识别已结束");
    };

    // 语音识别错误事件
    recognition.value.onerror = (event) => {
      console.error("语音识别错误:", event.error);
    };
    recognition.value.onresult = (event) => {
      let transcript = "";
      for (let i = event.resultIndex; i < event.results.length; ++i) {
        if (event.results[i].isFinal) {
          transcript += event.results[i][0].transcript;
        }
      }
      userInput.value += transcript;
    };
  }
};

recorder.value = new Recorder({
  sampleRate: 16000, // 采样率 16 kHz
  sampleBits: 16,    // 位长 16 bit
  numChannels: 1,    // 单声道
});
// 开始录音
const startRecording = async () => {
  // 暂停播放
  if (isPlaying.value) {
    togglePlayback();
  }
  try {
    await Recorder.getPermission();
    if (hasStopRecording.value) {
      recorder.value.resume();
      startRecognition();
      ElMessage.success("恢复录音");
    } else {
      ElMessage.success("开始录音");
      recorder.value.start(); // 开始录音
      startRecognition();
    }
    isRecording.value = true;
    console.log(isRecording.value)
  } catch (error) {
    ElMessage.info("请先允许该网页使用麦克风");
    console.log(`${error.name} : ${error.message}`);
  }
};

// 暂停录音
const stopRecording = async() => {
  if(!isRecording.value){
    ElMessage("暂未开始录音")
    return;
  }
  recorder.value.pause(); // 暂停录音
  await stopRecognition();
   // 等待一小段时间让识别结果完成处理
  await new Promise(resolve => setTimeout(resolve, 300));
  
  console.log("识别结果：", resultText.value);
  // 只有当有识别结果时才追加
  if (resultText.value) {
    userInput.value += resultText.value;
    ElMessage.success("语音识别完成");
  } else {
    ElMessage.warning("未识别到有效语音");
  }
  hasStopRecording.value = true;
  isRecording.value = false
};

// 重新录音录音、、
const resetRecording = async() => {
  // 暂停播放
  if (isPlaying.value) {
    togglePlayback();
  }

  ElMessage.success("重置录音");
  initRecognitionValue()
  await nextTick(); // 等待 DOM 更新
  hasStopRecording.value = false;
  hasStartPlay.value = false;
  playTime.value = 0;
  recorder.value.destroy();
  resultText.value = "";
  timer.value = null;
};

const hasStartPlay = ref(false);
const togglePlayback = () => {
  if (!isPlaying.value) {
    if (hasStartPlay.value) {
      recorder.value.resumePlay();
    } else {
      recorder.value.play();
      hasStartPlay.value = true;
    }
    // 播放时长
    timer.value = setInterval(() => {
      try {
        playTime.value = recorder.value.getPlayTime();
        // 判断是否播放结束
        if (recorder.value && playTime.value >= recorder.value.duration) {
          clearInterval(timer.value);
          isPlaying.value = false;
          hasStartPlay.value = false;
          playTime.value = 0;
        }
      } catch (error) {
        clearInterval(timer.value);
        timer.value = null;
      }
    }, 100);
    isPlaying.value = true;
  } else {
    recorder.value.pausePlay();
    playTime.value = recorder.value.getPlayTime();
    clearInterval(timer.value);
    timer.value = null;
    isPlaying.value = false;
  }
};

const voiceAnalysis = ref(null);
const sendMessage = () => {
  if (userInput.value.trim() === '') return;
   // 添加"正在思考中"提示
   const thinkingMessage = { 
    sender: 'ai', 
    text: 'Thinking...', 
    isThinking: true, // 添加标记表示这是思考中的临时消息
    isPlaying: false,
    voiceCode: voiceCode.value || 0
  };
  isLoading.value = true;
  // 上传录制的语音文件
  if (recorder.value && recorder.value.getWAVBlob) {
    recorder.value.stop(); // 确保录音已停止
    let wavBlob = recorder.value.getWAVBlob();
    let fileName = `${userId}_${assignmentId}_${Date.now()}`;
    let renameFile = new File([wavBlob], fileName + '.wav', { type: 'audio/wav' });

    // 调用 API 上传文件
    fileApis.uploadFile(renameFile)
      .then((uploadRes) => {
        console.log('文件上传成功:', uploadRes.data.data.split('?')[0]);
        chatMessages.value.push({ sender: 'user', text: userInput.value, audioUrl: uploadRes.data.data, isPlaying: false });
        ElMessage.success('语音上传成功');
        chatMessages.value.push(thinkingMessage);
        scrollToBottom();
        // 发送消息给 AI
        doubaoApis.sendMessage(userId, assignmentId, userInput.value, uploadRes.data.data.split('?')[0], recorder.value.duration, voiceCode.value)
          .then((res) => {
            if (res.data.code === 200) {
              // 移除"正在思考中"消息
              chatMessages.value = chatMessages.value.filter(msg => !msg.isThinking);
              isLoading.value = false;
              // 添加 AI 回复到聊天记录
              const aiMessage = { sender: 'ai', text: res.data.data.message, audioUrl: res.data.data.audioUrl, voiceCode: voiceCode.value, isPlaying: false };
              chatMessages.value.push(aiMessage);
              // 自动播放 AI 回复的音频
              autoPlay(aiMessage);
              mediaApis.getAudioSentiment(userId, assignmentId, -1)
              .then(res => {
                const emotion = res.data.data
                mediaApis.getAudioScore(userId, assignmentId,-1)
                .then(score => {
                  console.log(score.data.data)
                  const data = score.data.data
                  voiceAnalysis.value.addAnalysisResult({
                  content:data.content,
                  accuracyScore: data.accuracyScore,
                  fluencyScore: data.fluencyScore,
                  integrityScore: data.integrityScore,
                  standardScore: data.standardScore,
                  totalScore: data.totalScore,
                  wordScoreList: data.wordScoreList,
                  emotion:emotion
                });
                })
              }).catch(err =>{
                ElMessage('分析出错啦')
                isLoading.value = false
              })
            } else {
              // 移除"正在思考中"消息
              chatMessages.value = chatMessages.value.filter(msg => !msg.isThinking);
              chatMessages.value.push({ sender: 'ai', text: '服务器繁忙，请稍后再试...', isPlaying: false });
              isLoading.value = false;
            }
            scrollToBottom()
            initRecognitionValue();
          })
          .catch((err) => {
            // 移除"正在思考中"消息
            chatMessages.value = chatMessages.value.filter(msg => !msg.isThinking);
            console.error('AI 响应失败:', err);
            // 判断是否是超时错误
            const errorMessage = err.code === 'ECONNABORTED' || err.message.includes('timeout') 
              ? 'AI 响应超时，但消息可能已发送成功，请稍后刷新查看' 
              : '服务器繁忙，请稍后再试...';
            chatMessages.value.push({ sender: 'ai', text: errorMessage, isPlaying: false });
            isLoading.value = false;
            // 如果是超时，建议刷新获取最新消息
            if (err.code === 'ECONNABORTED' || err.message.includes('timeout')) {
              ElMessage.warning('响应超时，建议稍后刷新页面查看 AI 回复');
            }
          });
      })
      .catch((uploadErr) => {
        console.error('文件上传失败:', uploadErr);
        ElMessage.error('文件上传失败');
        isLoading.value = false;
      });
  }
};


let audio = null;
// 播放音频
const autoPlay = (message) => {
  if (message.audioUrl) {
    // 如果当前有音频正在播放，则暂停
    if (audio && !audio.paused) {
      audio.pause();
      audio.onended = null; // 移除之前的 onended 回调
    }
    // 创建新的音频对象并播放
    audio = new Audio(message.audioUrl);
    audio.play();
    message.isPlaying = true;
    // 播放结束后更新状态
    audio.onended = () => {
      message.isPlaying = false;
    };
  } else {
    ElMessage.warning('该消息没有语音文件');
  }
};

const playAudio = (message) => {
  if(isLoading.value) {
    ElMessage.warning('正在发送中，无法处理语音');
  }
  if (message.audioUrl) {
    if (message.isPlaying) {
      // 如果正在播放，则暂停
      audio.pause();
      message.isPlaying = false;
    } else {
      if (audio && !audio.paused) {
        audio.pause();
        audio.onended = null; // 移除之前的 onended 回调
      }
      // 如果未播放，则开始播放
      audio = new Audio(message.audioUrl);
      audio.play();
      message.isPlaying = true;
      audio.onended = () => {
        message.isPlaying = false; // 播放结束后更新状态
      };
    }
  } else {
    ElMessage.warning('该消息没有语音文件');
  }
};

// 返回按钮点击事件处理函数
const goBack = () => {
  // 这里可以添加具体的返回逻辑，比如返回上一个页面
  //http://127.0.0.1:4000/home/homeworkDetail/3054
  router.go(-1)
};

// 开始计时的变量
let homeworkStartTime = null;
const cameraPreview = ref(null);
const recordingDuration = ref(0); // 录制时长（秒）
let recordingTimer = null; // 录制计时器

const lastSavePromptTime = ref(0); // 记录上次提示保存的时间点
const SAVE_REMINDER_INTERVAL = 180; // 3分钟（180秒）提醒一次
// 开始作业
const startHomework = async () => {
  scrollToBottom();
  if(isHomeworkSubmitted.value){
    router.push({
      path: `/home/assignment/${assignmentId}/airecord`,
      query:{
        userId: userId,
        assignmentId: assignmentId,
        assignmentName: aiSpeakingAssignmentInfo.value.assignmentName
      }});
    return;
  }
  if (isHomeworkStarted.value) {
    ElMessage.warning("作业进行中");
    return;
  }
  try {
    const stream = await navigator.mediaDevices.getUserMedia({
      video: true,
      audio: true,
    });
    console.log("摄像头媒体流获取成功:", stream); // 添加日志
    isHomeworkStarted.value = true;
    isHomeworkSaved.value = false;
    homeworkStartTime = Date.now();
    doubaoApis.getRestricData(userId, assignmentId)
    .then(res =>{
    recordingDuration.value = +Number(res.data.data.recordTime).toFixed(0);
      // 启动录制时长计时器
    recordingTimer = setInterval(() => {
      recordingDuration.value += 1;

      // 每3分钟提醒保存一次（180秒）
      if (recordingDuration.value % SAVE_REMINDER_INTERVAL === 0 && 
          recordingDuration.value !== lastSavePromptTime.value) {
        lastSavePromptTime.value = recordingDuration.value;
        ElMessage.warning('录制时长已超过3分钟，建议暂存当前进度');
  }
    }, 1000);
     // 将摄像头画面绑定到 video 元素
     if (cameraPreview.value) {
      cameraPreview.value.srcObject = stream;
      console.log("摄像头画面已绑定到 video 元素:", cameraPreview.value.srcObject); // 添加日志
    }
    mediaRecorder.value = new MediaRecorder(stream);
    mediaRecorder.value.ondataavailable = (event) => {
      if (event.data.size > 0) {
        recordedChunks.value.push(event.data);
      }
    };
    mediaRecorder.value.start();
    })
    
  } catch (error) {
    console.error("获取摄像头和麦克风媒体流失败:", error);
    ElMessage.error('获取摄像头和麦克风媒体流失败')
    isHomeworkStarted.value = false;
  }
};

// 暂存作业
const saveHomework = async () => {
  if (!isHomeworkStarted.value) {
    ElMessage.warning("作业未开始，无法暂存");
    return;
  }
  if (isHomeworkSubmitted.value) {
    ElMessage.warning("作业已提交，无法暂存");
    return;
  }

  // 显示加载状态
  const loadingInstance = ElLoading.service({
    lock: true,
    text: '正在暂存作业，请稍候...',
    background: 'rgba(0, 0, 0, 0.1)'
  });
  if (isHomeworkStarted.value && !isHomeworkSubmitted.value) {
    if (mediaRecorder.value && mediaRecorder.value.state === "recording") {
      mediaRecorder.value.stop();
      mediaRecorder.value.onstop =async () => {
        // 记录结束时间
        const homeworkEndTime = Date.now();
        // 计算耗时（单位：秒）
        const duration = (homeworkEndTime - homeworkStartTime) / 1000;
        const videoBlob = new Blob([...recordedChunks.value], { type: "video/webm" });
        const fileName = `user_${userId}_${assignmentId}_${Date.now()}`;
        let renameFile =new File([videoBlob], fileName +'.webm', { type: 'video/webm' })

        try {
          doubaoApis
          .saveSigment(userId, assignmentId,renameFile, duration)
          .then(res =>{
            recordedChunks.value = [];
            isHomeworkSaved.value = true;
            hasHomeworkSaved.value = true;
            isHomeworkStarted.value = false;
            ElMessage.success("视频片段暂存成功");
            loadingInstance.close();
            lastSavePromptTime.value = 0; // 重置提示计时
          })
        } catch (error) {
          console.error("视频片段上传失败:", error);
          ElMessage.error("视频片段上传失败");
          loadingInstance.close();
        }
      };
    } else {
      ElMessage.error('状态出错啦')
      loadingInstance.close();
    }
    if (mediaRecorder.value && mediaRecorder.value.stream) {
      mediaRecorder.value.stream.getTracks().forEach((track) => track.stop());
    }
     // 停止录制时长计时器
  if (recordingTimer) {
    clearInterval(recordingTimer);
    recordingTimer = null;
  }

    // 清除摄像头画面
    if (cameraPreview.value) {
      cameraPreview.value.srcObject = null;
    }

    initRecognitionValue()
    console.log(mediaRecorder.value.state);
  }
};

// 安全的头像获取方法
const getAvatar = (voiceCode) => {
  if (voiceCode === null || voiceCode === undefined) {
    return voiceOptions.value[0]?.avatar || userAvatar;
  }
  return voiceOptions.value[voiceCode]?.avatar || voiceOptions.value[0]?.avatar || gavinAvatar;
};

// 安全的语音选项获取方法
const getVoiceOption = (voiceCode) => {
  if (voiceCode === null || voiceCode === undefined) {
    return voiceOptions.value[0];
  }
  return voiceOptions.value[voiceCode] || voiceOptions.value[0];
};

// 文档预览相关
const open = ref(false)
const alertProps = reactive({
  open: open.value,
  onOk: () => (open.value = false),
  onCancel: () => (open.value = false),
});

const docxInfo = reactive({
  docxUrl: '',
  docxTitle: '',
});

// 打开文档编辑器
const openEditor = (url, title) => {
  open.value = true;
  docxInfo.docxUrl = url;
  docxInfo.docxTitle = title;
  Object.assign(alertProps, {
    open: open.value,
    onCancel: () => {
      open.value = false
      Object.assign(alertProps,{
        open: open.value,
        onOk: () => (open.value = false),
        onCancel: () => (open.value = false),
      })
      Object.assign(docxInfo, {
        docxUrl: url,
        docxTitle: title,
      })
    },
  })
  Object.assign(docxInfo, {
    docxUrl: url,
    docxTitle: title,
  })
};

// 格式化录制时长
const formatDuration = (duration) => {
  const minutes = Math.floor(duration / 60);
  const seconds = duration % 60;
  return `${minutes}:${seconds.toString().padStart(2, '0')}`;
};

// 重试作业
const resetHomework = async() => {
  if (isHomeworkSubmitted.value) {
    ElMessage.warning("作业已提交，无法重试");
    return;
  }
  if (isHomeworkStarted.value) {
    // 停止录制时长计时器
    if (recordingTimer) {
      clearInterval(recordingTimer);
      recordingTimer = null;

    }
    // 清除摄像头画面
    if (cameraPreview.value) {
      cameraPreview.value.srcObject = null;
    }
     // 关闭摄像头和麦克风
     if (mediaRecorder.value && mediaRecorder.value.stream) {
              mediaRecorder.value.stream.getTracks().forEach((track) => track.stop());
      }
  }

   // 显示加载状态
   const loadingInstance = ElLoading.service({
    lock: true,
    text: '正在重置作业，请稍候...',
    background: 'rgba(0, 0, 0, 0.2)'
  });
  doubaoApis.deleteChatHistory(userId, assignmentId, aiSpeakingAssignmentInfo.value.assignmentName, voiceCode.value )
  .then(res =>{
    if(res.data.code == 200){
      recordedChunks.value = [];
      chatMessages.value = [];
      isHomeworkSaved.value = false;
      isHomeworkStarted.value = false;
      initRecognitionValue()
      recordingDuration.value = 0;
      ElMessage.success("作业内容已清空");
      getHistory()
      lastSavePromptTime.value = 0; // 重置提示计时

    } else {
      ElMessage.error("清除失败，请稍后尝试")
    }
    // 隐藏加载状态
    loadingInstance.close();

  })
  .catch(err => {
    ElMessage.error("清除失败，请稍后尝试");
    // 隐藏加载状态
    loadingInstance.close();
  });
};

// 提交作业
const submitHomework = async () => {
  if (isHomeworkSubmitted.value) {
    ElMessage.warning("作业已提交，请勿重复提交");
    return;
  }
  if(isHomeworkStarted.value){
    ElMessage.warning("作业正在进行中，请暂存后再提交")
    return;
  }

  doubaoApis.getRestricData(userId, assignmentId)
  .then(res => {
    console.log(res.data.data)
    if(Number(res.data.data.chatTimes) < aiSpeakingAssignmentInfo.value.minInteraction){
      ElMessage.info(`交流次数小于${aiSpeakingAssignmentInfo.value.minInteraction}次，无法提交`);
      return;
    } else if(Number(res.data.data.recordTime) / 60 < aiSpeakingAssignmentInfo.value.minDuration){
      ElMessage.info(`交流时长小于${aiSpeakingAssignmentInfo.value.minDuration}分钟，无法提交`);
      return;
    } else {
        // 显示加载状态
        const loadingInstance = ElLoading.service({
          lock: true,
          text: '正在提交作业，请稍候...',
          background: 'rgba(0, 0, 0, 0.2)'
        });
          engagementApis.engagementSubmit(userId, assignmentId)
          .then(res => {
            doubaoApis.endChat(userId, assignmentId)
              .then(res => {
                  isHomeworkSubmitted.value = true;
                  initRecognitionValue()
                  getHistory()
                  ElMessage.success("作业已成功提交");
                  // 隐藏加载状态
                  loadingInstance.close();
              })
              .catch(err => {
                ElMessage.error('提交失败，请稍后再试'+ err)
                // 隐藏加载状态
                loadingInstance.close();
              })
          })
          .catch(err=> {
            ElMessage.error('提交失败，请稍后再试'+ err)
            // 隐藏加载状态
            loadingInstance.close();
          })
          
            // 关闭摄像头和麦克风
            if (mediaRecorder.value && mediaRecorder.value.stream) {
              mediaRecorder.value.stream.getTracks().forEach((track) => track.stop());
            }
    }
  })
   
};

// 根据作业状态返回对应的文本
const getStatusText = () => {
  if (isHomeworkSubmitted.value) {
    return "已提交";
  } else if (!isHomeworkStarted.value) {
    return hasHomeworkSaved.value ? "已暂存" : "待开始中";
  } else if (isHomeworkSaved.value) {
    return "暂存中";
  } else {
    return "进行中";
  }
};

// 格式化时间戳为 "月-日 时:分:秒"
const formatTimestamp = (timestamp) => {
  if(timestamp == null){
    return ''
  }
  const date = new Date(timestamp);

  // 获取月、日、时、分、秒
  const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从 0 开始，需要 +1
  const day = String(date.getDate()).padStart(2, '0');
  const hours = String(date.getHours()).padStart(2, '0');
  const minutes = String(date.getMinutes()).padStart(2, '0');
  const seconds = String(date.getSeconds()).padStart(2, '0');

  // 返回格式化后的时间字符串
  return `${month}-${day} ${hours}:${minutes}:${seconds}`;
};



const voiceInctanceKey = ref(0)
const getHistory = () =>{
  doubaoApis
  .getRecord(userId, assignmentId)
  .then(res =>{
    console.log(res.data.data)
    if(res.data.data.audioSigment && res.data.data.audioSigment.length == 0 ){
      hasHomeworkSaved.value = false;
    } else{
      hasHomeworkSaved.value = true;
    }
    isHomeworkSubmitted.value = res.data.data.hasCommitted || false;
    if(res.data.data.voiceCode != null){
      voiceCode.value = res.data.data.voiceCode;
    }
    voiceInctanceKey.value += 1;
  })
  doubaoApis
    .startChat(userId, assignmentId, aiSpeakingAssignmentInfo.value.assignmentName, voiceCode.value)
    .then((res) => {
      chatMessages.value = [];
      res.data.data.forEach(entry => {
      if (entry.role === 'user' &&!entry.content.startsWith('请你扮演')) {
        chatMessages.value.push({ sender: "user", text: entry.content, isPlaying: false, audioUrl: entry.audioUrl, time: entry.timestamp});
      } else if (entry.role === 'assistant') {
        chatMessages.value.push({ sender: "ai", text: entry.content, isPlaying: false, audioUrl: entry.audioUrl, time: entry.timestamp, voiceCode: entry.entryVoiceCode });
      }
  });
    })
    .catch((err) => {
      console.log(err);
    });
}
const chatContainerRef = ref(null); // 绑定 chat-messages 容器
// 滚动到底部方法
const scrollToBottom = () => {
      nextTick(() => {
        if (chatContainerRef.value) {
          chatContainerRef.value.scrollTop = chatContainerRef.value.scrollHeight;
        }
      });
  };

  const handleMessageClick = (message, index) => {
    console.log(message, index);
    console.log(voiceAnalysis.value.voiceAnalysisContainerRef)
  if (message.sender === 'user' && voiceAnalysis.value.voiceAnalysisContainerRef) {
    const analysisResultElements = voiceAnalysis.value.voiceAnalysisContainerRef.querySelectorAll('.analysis-result');
    if (analysisResultElements.length > (index -1) / 2) {
      const targetElement = analysisResultElements[(index - 1) / 2];
      nextTick(() => {
        targetElement.scrollIntoView({
          behavior: 'smooth',
          block: 'start'
        });
      });
    }
  }
};

onBeforeUnmount(() => {
   // 销毁录制时长计时器
   if (recordingTimer) {
    clearInterval(recordingTimer);
    recordingTimer = null;
  }

  if (mediaRecorder.value && mediaRecorder.value.stream) {
    mediaRecorder.value.stream.getTracks().forEach((track) => track.stop());
  }
  if (cameraPreview.value) {
    cameraPreview.value.srcObject = null;
  }
  lastSavePromptTime.value = 0; // 清理计时
});


onMounted(() => {
  aiSpeakingAssignmentApis.getAiSpeakingAssignmentById(assignmentId)
  .then(res => {
    aiSpeakingAssignmentInfo.value = res.data.data;
    getHistory();
  })

  doubaoApis.getRestricData(userId, assignmentId)
    .then(res =>{
      recordingDuration.value = +Number(res.data.data.recordTime).toFixed(0);
    })
});
</script>

<style scoped>

.app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
    color: #2c3e50;
    margin: 0;
    padding: 0;
}

.main-container {
  display: flex;
   /* 修改后 */
  height: 88vh; /* 使用视口高度 */
  width: 90vw;  /* 使用视口宽度 */
  max-width: 1600px; /* 设置最大宽度 */
  margin: 2% auto; /* 居中显示 */
  margin-left: 5%;
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}


.info-container {
  width: 22%;
  padding: 30px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  text-align: left;
  background-color: #e1f5fe; /* 信息区背景色 */
}

.back-button{
  font-size: 30px;
  margin-right: 150px;
}



.main-button{
  width:80px;
  display: inline-block;
  margin-left:-10px;
  font-size: 13px;
  height: 30px;
}

.task-name {
  font-size: 22px;
  margin-bottom: 10px;
  color: #0277bd;
}

.task-time {
  color: #78909c;
  font-size: 12px;
  margin-bottom: 20px;
}

.task-description {
  margin-bottom: 12px;
  color: #546e7a;
}

.task-file,
.task-attachments {
  margin-bottom: 6px;
  color: #546e7a;
}

.card {
    background-color: rgba(255, 255, 255, 0.4);
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    padding: 10px;
    max-width: 350px;
    font-family: Arial, sans-serif;
  }
  .card-header {
    border-bottom: 1px solid #eee;
    padding-bottom: 8px;
    margin-bottom: 20px;
  }
  .card-title {
    font-size: 20px;
    font-weight: bold;
    color: #546e7a;
  }
  .data-item {
    margin-bottom: 10px;
  }
  .data-label {
    color: #546e7a;
    margin-right: 8px;
    font-weight: bold;
  }
  .data-value {
    color: #777;
  }


  .scrollable-description {
  max-height: 12em; /* 10行高度（假设1em=1行） */
  line-height: 1.3em; /* 行高设定 */
  overflow-y: auto; /* 垂直滚动 */
  white-space: pre-wrap; /* 保留换行符 */
  color: #777;
  margin-top: 10px;
  scrollbar-width: none; /* Firefox */
  -ms-overflow-style: none; /* IE/Edge */
}



.homework-button-group {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: auto;
  margin-left: 40px;
  border:none;
}

.start-homework-button {
  margin-left: 10px;
  background-color: #90caf9;
  color: #0d47a1;
  width: 100px;
  border:none;
}

.save-homework-button {
  background-color: #fff59d;
  color: #f57f17;
  width: 100px;
  border:none;
}

.reset-homework-button {
  background-color: #ffcdd2;
  color: #b71c1c;
  width: 100px;
  border:none;
}

.submit-homework-button {
  background-color: #a5d6a7;
  color: #1b5e20;
  width: 100px;
  border:none;
}

.chat-container-wrapper {
  width: 75%;
  min-width: 500px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  height: 100%;
  position: relative;
  background-color: #fafafa; /* 问答区背景色 */
}

.voice-analysis-container {
  display: flex;
  box-sizing: border-box;
  flex-direction: column;
  position: relative;
  width: 40%;
  background-color: #e1f5fe; /* 信息区背景色 */
}

.ai-message.is-thinking .message-text {
  color: #999;
  font-style: italic;
}

.card-wrapper {
  display: flex;
  align-items: center;
}
.card-header {
  flex: 0 0 auto;
  margin: 0 auto;
  font-weight: bold;
}
.status-label-wrapper {
  display: flex;
  padding: 10px;
}

.status-label-wrapper span {
  padding: 4px 45px;
  border-radius: 4px;
  font-size: 14px;
}

.status-default {
  background-color: #e0e0e0;
  color: #757575;
}

.status-started {
  background-color: #90caf9;
  color: #0d47a1;
}

.status-saved {
  background-color: #fff59d;
  color: #f57f17;
}

.status-submitted {
  background-color: #a5d6a7;
  color: #1b5e20;
}

.chat-container {
  box-sizing: border-box;
  display: flex;
  height: 100%;
  overflow: hidden;
  flex-direction: column;
  border-bottom: 1px solid #e0e0e0;
}

.card-header-fixed {
  position: sticky;
  top: 0;
  z-index: 10;
}



.chat-messages {
  flex: 1;
  padding: 10px;
  overflow-y: auto;
  max-height: calc(100vh - 300px);  /* 关键：确保它不会超出屏幕 */
  scrollbar-width: none; /* Firefox */
}

.chat-messages::-webkit-scrollbar {
  display: none; /* Chrome, Safari */
}

.user-message {
  display: flex;
  justify-content: flex-start;
  text-align: left;
  margin: 10px;
  flex-direction: row-reverse;
  margin-bottom: 30px;
}

.ai-message {
  display: flex;
  justify-content: flex-start;
  text-align: left;
  margin: 5px;
  margin-bottom: 10px;
}

.message-content {
  display: flex;
  flex-direction: column; /* 竖直排列 */
  max-width: 95%;
}

.message-text {
  background-color: #e0f7fa;
  padding: 4px;
  border-radius: 5px;
  margin: 0 5px;
  align-self: flex-start;
  color: #006064;
  font-size: 14px;
}

.message-time {
  font-size: 12px;
  color: #999;
  margin-top: 4px; /* 调整时间戳与消息内容的间距 */
  margin-left: 15px;
}

.ai-message .message-text {
  background-color: #f1f8e9;
  color: #33691e;
}

.input-container {
  display: flex;
  padding: 10px;
  position: sticky;
  bottom: 0;
  background-color: #fff;
  z-index: 1;
  border-top: 1px solid #e0e0e0;
}

.input-container input {
  flex: 1;
  padding: 6px;
  border: 1px solid #bdbdbd;
  border-radius: 4px;
}

.input-container el-button {
  margin-left: 10px;
}

/* 开始按钮样式 */
.start-button {
  margin-left: 10px;
  background-color: #90caf9;
  color: #0d47a1;
  border: none;
}

/* 结束按钮样式 */
.stop-button {
  background-color: #ffcdd2;
  color: #b71c1c;
  border:none;
}

/* 重新按钮样式 */
.reset-button {
  background-color: #fff59d;
  color: #f57f17;
  border:none;
}

/* 发送按钮样式 */
.send-button {
  background-color: #a5d6a7;
  color: #1b5e20;
  border:none;
}

.recording-bar {
  display: flex;
  align-items: center;
  gap: 10px;
}

progress {
  margin-left: 20px;
  /* 设置宽度和高度 */
  width: 200px;
  height: 15px;
  /* 设置边框和圆角 */
  border: none;
  border-radius: 10px;
  /* 隐藏溢出部分 */
  overflow: hidden;
}

.wechat-audio-button {
  margin-left: 25px;
  display: flex;
  align-items: center;
  background-color: #90caf9;
  border: none;
  border-radius: 15px;
  padding: 8px 15px;
  cursor: pointer;
  transition: background-color 0.3s;
  margin-bottom:8px;
}

.wechat-audio-button:hover {
  background-color: #e0e0e0;
}

.wechat-audio-button .icon {
  display: inline-block;
  width: 12px;
  height: 12px;
  margin-right: 8px;
  background-size: cover;
}

.wechat-audio-button .play {
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>');
}

.wechat-audio-button .pause {
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="6" y="4" width="4" height="16"></rect><rect x="14" y="4" width="4" height="16"></rect></svg>');
}

.wechat-audio-button .text {
  font-size: 14px;
  color: #333;
}

.ai-message .el-button {
  margin-left: 10px;
  background-color: transparent;
  border: none;
  color: #33691e;
}

.ai-message .el-button:hover {
  background-color: #f1f8e9;
}

.camera-preview {
  position: fixed;
  top: 20px;
  right: 20px;
  width: 200px; /* 根据需要调整大小 */
  height: 150px; /* 根据需要调整大小 */
  border: 2px solid #ccc;
  border-radius: 10px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  z-index: 1000; /* 确保摄像头画面在最上层 */
}

.recording-duration {
  position: fixed;
  top: 180px; /* 根据 camera-preview 的高度调整 */
  right: 65px;
  font-size: 14px;
  color: #333;
  background-color: rgba(255, 255, 255, 0.8);
  padding: 4px 8px;
  border-radius: 4px;
  z-index: 1000;
}

</style>