<template>
  <div class="input-area-wrapper" @touchend="handleVoiceTouchEndFromContainer"
    @touchcancel="handleVoiceTouchEndFromContainer">
    <div v-if="!visibleWaveBtn || speechProvider !== 'wechat'"
      class="mx-[8px] mb-[6px] flex min-h-[42px] items-end rounded-[21px] bg-white px-[8px] py-[6px] shadow-[0_2px_12px_rgba(18,39,75,0.06)]">
      <!-- 语音/键盘切换 -->
      <div v-if="isSpeechRecognitionSupported" class="flex h-[30px] w-[30px] shrink-0 items-center justify-center"
        @click="toggleVoiceMode">
        <img class="h-[22px] w-[22px]" v-if="!isVoiceMode"
          src="https://oss.nianxx.cn/mp/static/version_101/home/input_voice_icon.png" />
        <img class="h-[22px] w-[22px]" v-else
          src="https://oss.nianxx.cn/mp/static/version_101/home/input_keyboard_icon.png" />
      </div>

      <!-- 输入框/语音按钮容器 -->
      <div class="min-w-0 flex-1" :class="{ 'pl-[4px]': !isSpeechRecognitionSupported }">
        <textarea ref="textareaRef" v-if="!isVoiceMode" v-model="inputMessage" rows="1" maxlength="300"
          :placeholder="placeholder"
          class="block h-[22px] max-h-[92px] min-h-[22px] w-full resize-none overflow-x-hidden overflow-y-auto border-0 bg-transparent p-0 text-[14px] leading-[22px] text-[#333] outline-none appearance-none placeholder:text-[#A5AAB4] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
          @input="adjustTextareaHeight" @focus="handleFocus" @blur="handleBlur" @touchstart="handleTouchStart"
          @touchend="handleTouchEnd" />


        <div v-if="isVoiceMode"
          class="flex h-[36px] w-full select-none items-center justify-center bg-transparent text-[14px] leading-[22px] text-[#333] active:bg-gray-100"
          @longpress="handleVoiceTouchStart" @touchend="handleVoiceTouchEnd" @touchcancel="handleVoiceTouchEnd">
          按住 说话
        </div>
      </div>

      <div class="flex h-[30px] w-[34px] shrink-0 items-center justify-end">
        <div
          class="flex h-[30px] w-[30px] items-center justify-center rounded-full [background:radial-gradient(39%_39%_at_97%_81%,#79dffb_0%,rgba(138,227,252,0)_100%),radial-gradient(54%_54%_at_3%_70%,#8afcf8_0%,rgba(138,252,248,0)_100%),#0CCD58] shadow-[0_4px_10px_rgba(12,205,88,0.22)]"
          @click="sendMessage">
          <div v-if="isSessionActive" class="h-[10px] w-[10px] rounded-[3px] bg-white"> </div>
          <img v-else class="h-[20px] w-[20px]"
            src="https://oss.nianxx.cn/mp/static/version_101/home/input_send_icon.png" />
        </div>
      </div>
    </div>


    <!-- 录音按钮 -->
    <RecordingWaveBtn v-if="visibleWaveBtn" ref="recordingWaveBtnRef" />

    <div class="text-center text-[9px] leading-[12px] text-[#A5AAB4]">
      内容由AI大模型生成，请仔细鉴别
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, nextTick, onMounted, defineExpose, onUnmounted } from "vue";
import RecordingWaveBtn from "@/components/Speech/RecordingWaveBtn.vue";


let manager = null;
let speechProvider = "";
const isSpeechRecognitionEnabled = ref(true);
const isSpeechRecognitionSupported = ref(true);
let appSpeechOptions = {};

const props = defineProps({
  modelValue: String,
  holdKeyboard: Boolean,
  isSessionActive: Boolean,
  stopRequest: Function,
});
const emit = defineEmits([
  "update:modelValue",
  "send",
  "noHideKeyboard",
  "keyboardShow",
  "keyboardHide",
  "sendVoice",
]);

const textareaRef = ref(null);
const recordingWaveBtnRef = ref(null);
const appSpeechRef = ref(null);
const appSpeechKey = ref(0);
const appSpeechVisible = ref(true);
const placeholder = ref("快告诉小七您在想什么~");
const inputMessage = ref(props.modelValue || "");
const maxTextareaHeight = 92;
const isFocused = ref(false);
const keyboardHeight = ref(0);
const isVoiceMode = ref(false);
const visibleWaveBtn = ref(false);
const isRecording = ref(false);
const isVoicePressing = ref(false);
const appRecognizedText = ref("");
const isAppSpeechStarting = ref(false);
const isAppWaitingToSend = ref(false);
let watchDogTimer = null;
let appStopFallbackTimer = null;
let hasSentAppRecognition = false;

const resetUI = () => {
  isRecording.value = false;
  visibleWaveBtn.value = false;
  try {
    if (recordingWaveBtnRef.value) {
      recordingWaveBtnRef.value.stopAnimation();
    }
  } catch (e) {
    console.error("resetUI stopAnimation error", e);
  }
  if (watchDogTimer) {
    clearTimeout(watchDogTimer);
    watchDogTimer = null;
  }
};

const startWatchDog = (timeout = 10000) => {
  if (watchDogTimer) clearTimeout(watchDogTimer);
  watchDogTimer = setTimeout(() => {
    watchDogTimer = null;
    console.warn("recording watchdog triggered, forcing UI reset");
    if (speechProvider === "app" && hasActiveVoiceRecognition()) {
      stopActiveVoiceRecognition({ shouldSend: true });
      return;
    }
    resetUI();
  }, timeout);
};

const adjustTextareaHeight = () => {
  const textarea = textareaRef.value;
  if (!textarea) return;

  textarea.style.height = "22px";
  textarea.style.height = `${Math.min(textarea.scrollHeight, maxTextareaHeight)}px`;
};

const clearAppStopFallback = () => {
  if (appStopFallbackTimer) {
    clearTimeout(appStopFallbackTimer);
    appStopFallbackTimer = null;
  }
};

const showRecordingUI = () => {
  isRecording.value = true;
  visibleWaveBtn.value = true;

  nextTick(() => {
    if (recordingWaveBtnRef.value) {
      recordingWaveBtnRef.value.startAnimation();
    }
  });
  startWatchDog(10000);
};

const resetAppSpeechComponent = () => {
  if (speechProvider !== "app") return;

  isAppSpeechStarting.value = false;
  appSpeechVisible.value = false;
  nextTick(() => {
    appSpeechKey.value += 1;
    appSpeechVisible.value = true;
  });
};

const getPendingAppSpeechText = () => {
  return (appRecognizedText.value || inputMessage.value || "").trim();
};

const scheduleAppRecognizedTextSend = (timeout = 1200) => {
  isAppWaitingToSend.value = true;
  clearAppStopFallback();

  if (getPendingAppSpeechText()) {
    sendAppRecognizedText();
    return;
  }

  appStopFallbackTimer = setTimeout(() => {
    appStopFallbackTimer = null;
    sendAppRecognizedText();
  }, timeout);
};

// 保持和父组件同步
watch(
  () => props.modelValue,
  (val) => {
    inputMessage.value = val;
    nextTick(adjustTextareaHeight);
  }
);

// 当子组件的 inputMessage 变化时，通知父组件（但要避免循环更新）
watch(inputMessage, (val) => {
  // 只有当值真正不同时才emit，避免循环更新
  if (val !== props.modelValue) {
    emit("update:modelValue", val);
  }
  nextTick(adjustTextareaHeight);
});

// 切换语音/文本模式
const toggleVoiceMode = () => {
  if (!isSpeechRecognitionSupported.value) return;
  if (speechProvider === "app" && isVoiceMode.value) {
    stopActiveVoiceRecognition({ shouldSend: false });
  }
  isVoiceMode.value = !isVoiceMode.value;
};

// 处理语音按钮按下开始
const handleVoiceTouchStart = () => {
  if (!isSpeechRecognitionSupported.value) return;
  if (isRecording.value || isAppSpeechStarting.value || visibleWaveBtn.value) return;

  isVoicePressing.value = true;

  try {
    if (speechProvider === "wechat") {
      if (!manager) return;
      manager.start({ lang: "zh_CN" });
      showRecordingUI();
    } else if (speechProvider === "app") {
      if (!appSpeechOptions.apikey) {
        showToast("请先配置语音识别API Key");
        return;
      }

      appRecognizedText.value = "";
      inputMessage.value = "";
      isAppWaitingToSend.value = false;
      hasSentAppRecognition = false;
      clearAppStopFallback();
      isAppSpeechStarting.value = true;

      const appSpeech = appSpeechRef.value;
      if (!appSpeech || typeof appSpeech.start !== "function") {
        isAppSpeechStarting.value = false;
        showToast("语音组件未初始化");
        return;
      }

      appSpeech.start();
    } else {
      return;
    }
  } catch (err) {
    console.error("record start error:", err);
    isAppSpeechStarting.value = false;
    // 保底清理
    resetUI();
  }
};

const hasActiveVoiceRecognition = () => {
  return (
    isVoicePressing.value ||
    isRecording.value ||
    isAppSpeechStarting.value ||
    visibleWaveBtn.value
  );
};

const stopActiveVoiceRecognition = ({ shouldSend = true } = {}) => {
  isVoicePressing.value = false;

  if (!isSpeechRecognitionSupported.value) {
    resetUI();
    return;
  }

  if (speechProvider === "app") {
    const wasStarting = isAppSpeechStarting.value;
    const wasRecording = isRecording.value;

    if (!wasStarting && !wasRecording) {
      if (!shouldSend) {
        isAppWaitingToSend.value = false;
        clearAppStopFallback();
        resetAppSpeechComponent();
      }
      resetUI();
      return false;
    }

    isAppSpeechStarting.value = false;

    try {
      appSpeechRef.value?.stop?.();
      if (wasRecording && shouldSend) {
        scheduleAppRecognizedTextSend();
      } else {
        isAppWaitingToSend.value = false;
        clearAppStopFallback();
        resetAppSpeechComponent();
      }
    } catch (err) {
      console.error("record stop error:", err);
      resetAppSpeechComponent();
    } finally {
      resetUI();
    }
    return true;
  }

  // 如果本地状态不是录音中，也确保 UI 恢复
  if (!isRecording.value) {
    if (recordingWaveBtnRef.value) {
      recordingWaveBtnRef.value.stopAnimation();
    }
    visibleWaveBtn.value = false;
    if (watchDogTimer) {
      clearTimeout(watchDogTimer);
      watchDogTimer = null;
    }
    return false;
  }

  try {
    manager?.stop?.();
  } catch (err) {
    console.error("record stop error:", err);
  } finally {
    // 无论 stop 是否抛错，都保证 UI 恢复
    resetUI();
  }
  return true;
};

// 处理语音按钮长按结束
const handleVoiceTouchEnd = () => {
  stopActiveVoiceRecognition({ shouldSend: true });
};

const handleVoiceTouchEndFromContainer = () => {
  if (speechProvider !== "app") return;
  if (!hasActiveVoiceRecognition()) return;
  stopActiveVoiceRecognition({ shouldSend: true });
};

// 处理发送原语音
const initRecord = () => {
  if (!manager) return;

  manager.onRecognize = (res) => {
    let text = res.result || "";
    inputMessage.value = text;
  };
  // 识别结束事件
  manager.onStop = (res) => {
    console.log(res, 37);
    let text = (res && res.result) || "";

    // 保证 UI 恢复（防止未走 handleVoiceTouchEnd）
    resetUI();

    if (text === "") {
      console.log("没有说话");
      return;
    }

    inputMessage.value = text;
    // 在语音识别完成后发送消息
    emit("send", text);
  };

  // 错误处理，确保 UI 重置
  manager.onError = (err) => {
    console.error("record manager error", err);
    resetUI();
  };
};

const getAppSpeechText = (res) => {
  return (
    res?.sentence?.text ||
    res?.text ||
    res?.result ||
    res?.payload?.output?.sentence?.text ||
    ""
  );
};

const sendAppRecognizedText = () => {
  if (hasSentAppRecognition) return false;

  const text = getPendingAppSpeechText();
  if (!text) {
    console.log("没有说话");
    return false;
  }

  hasSentAppRecognition = true;
  isAppWaitingToSend.value = false;
  clearAppStopFallback();
  inputMessage.value = text;
  emit("send", text);
  appRecognizedText.value = "";
  return true;
};

const handleAppSpeechResult = (res) => {
  if (hasSentAppRecognition) return;

  const text = getAppSpeechText(res);
  if (!text) return;

  appRecognizedText.value = text;
  inputMessage.value = text;

  if (isAppWaitingToSend.value) {
    sendAppRecognizedText();
  }
};

const handleAppSpeechChange = (msg) => {
  if (!msg || !msg.status) return;

  if (msg.status === "START") {
    isAppSpeechStarting.value = false;
    if (!isVoicePressing.value) {
      appSpeechRef.value?.stop?.();
      resetAppSpeechComponent();
      resetUI();
      return;
    }

    showRecordingUI();
    return;
  }

  if (msg.status === "STOP") {
    isAppSpeechStarting.value = false;
    resetUI();
    if (!sendAppRecognizedText() && !isAppWaitingToSend.value) {
      resetAppSpeechComponent();
    }
    return;
  }

  if (msg.status === "FINISH") {
    isAppSpeechStarting.value = false;
    resetUI();
    sendAppRecognizedText();
    resetAppSpeechComponent();
    return;
  }

  if (msg.status === "CLOSE") {
    isAppSpeechStarting.value = false;
    resetUI();
    if (isAppWaitingToSend.value) {
      sendAppRecognizedText();
    }
    resetAppSpeechComponent();
    return;
  }

  if (msg.status === "ERROR") {
    console.error("app speech recognition error", msg.msg);
    isAppSpeechStarting.value = false;
    isAppWaitingToSend.value = false;
    clearAppStopFallback();
    resetUI();
    resetAppSpeechComponent();
  }
};

// 监听键盘高度变化
onMounted(() => {
  initRecord();
  nextTick(adjustTextareaHeight);
});

onUnmounted(() => {
  if (manager) {
    try {
      manager.stop && manager.stop();
    } catch (e) {
      // ignore
    }
    manager.onRecognize = null;
    manager.onStop = null;
    manager.onError = null;
  }
  if (appSpeechRef.value) {
    try {
      appSpeechRef.value.stop && appSpeechRef.value.stop();
    } catch (e) {
      // ignore
    }
  }
  clearAppStopFallback();
  isAppSpeechStarting.value = false;
  isAppWaitingToSend.value = false;
  isVoicePressing.value = false;
  resetUI();
});

const hideKeyboardAfterSend = () => {
  isFocused.value = false;

  const textarea = textareaRef.value;
  if (textarea && typeof textarea.blur === "function") {
    textarea.blur();
  }
};

const sendMessage = () => {
  if (props.isSessionActive) {
    // 如果会话进行中，调用停止请求函数
    if (props.stopRequest) {
      props.stopRequest();
    }
    hideKeyboardAfterSend();
  } else {
    // 否则发送新消息
    if (!inputMessage.value.trim()) return;
    emit("send", inputMessage.value);
    hideKeyboardAfterSend();
  }
};

const handleFocus = () => {
  isFocused.value = true;
  emit("noHideKeyboard");
};

const handleBlur = () => {
  isFocused.value = false;
};

const handleTouchStart = () => {
  emit("noHideKeyboard");
};

const handleTouchEnd = () => {
  emit("noHideKeyboard");
};

// 手动聚焦输入框
const focusInput = () => {
  isFocused.value = true;
  nextTick(() => {
    const textarea = textareaRef.value;
    if (textarea && typeof textarea.focus === "function") {
      textarea.focus();
    }
  });
};

// 手动失焦输入框
const blurInput = () => {
  isFocused.value = false;

  const textarea = textareaRef.value;
  if (textarea && typeof textarea.blur === "function") {
    textarea.blur();
  }
};

// 暴露方法给父组件
defineExpose({ focusInput, blurInput });
</script>
