<template>
  <div class="chat-input">
    <div class="chat-input-box">
      <div class="img-box" @click="isRecording = !isRecording">
        <img v-if="isRecording" src="../img/icon/keyboard.png" alt="" />
        <img v-else src="../img/icon/macphone.png" alt="" />
      </div>
      <div class="chat-input-box-main" :class="{ 'is-recording': isRecording }">
        <template v-if="isRecording">
          <div class="recording" @mousedown="handleMousedown" @mouseup="handleMouseup">
            <Recording v-if="recording" @on-complete="recordingComplete" />
            <span v-else>长按说话</span>
          </div>
        </template>
        <div v-if="!isRecording" class="textarea-box">
          <div
            ref="textareaRef"
            class="textarea-box-input"
            contenteditable="true"
            @input="handleInput"
            @keydown.enter.ctrl.prevent="keydownEnter"
            @keydown.enter.prevent.exact="throttleHandle"
          ></div>
          <!-- 模拟placeholder -->
          <div v-if="!inputText" class="textarea-content"> 请输入内容 </div>
        </div>
        <div class="upload-box">
          <!--          <div class="img-box upload-img">-->
          <!--            <img src="../img/icon/icon-image.png" alt="" />-->
          <!--            <input-->
          <!--              id="img-upload"-->
          <!--              type="file"-->
          <!--              accept="image/jpeg,image/jpg,image/png,image/gif"-->
          <!--              @change="getFile"-->
          <!--            />-->
          <!--          </div>-->
          <!--          <div class="img-box upload-file">-->
          <!--            <img src="../img/icon/icon-file.png" alt="" />-->
          <!--            <input-->
          <!--              id="img-upload"-->
          <!--              type="file"-->
          <!--              accept=".pdf,.doc,.docx,.xls,.xlsx"-->
          <!--              @change="getFile"-->
          <!--            />-->
          <!--          </div>-->
          <div v-if="!isRecording" class="send" @click="throttleHandle">
            <img src="../img/chat/send.png" alt="" />
          </div>
        </div>
      </div>
    </div>
    <!-- 弹窗 -->
    <AiMessage :message-option="messageOption" v-model:visible="messageVisible" />
  </div>
</template>

<script setup lang="ts">
import { _throttle } from '../utils'
import AiMessage from './AiMessage.vue'
import Recording from './Recording.vue'
import { ref } from 'vue'

const inputText = ref('') // 正在输入的值 可作为类placeholder的显示控制
const isRecording = ref(false) // 是否处于录音状态
const recording = ref(false) // 正在识别录音
const recordingTime = ref(0) // 录音时间 低于500ms 不进行
const messageVisible = ref(false)
const messageOption: Recordable = ref({})

const textareaRef = ref()

const emit = defineEmits(['handleSend'])

const handleSend = () => {
  emit('handleSend', inputText.value)
  textareaRef.value.innerText = ''
  inputText.value = ''
}
const handleInput = (text) => {
  inputText.value = text.target.textContent
}
// 输入节流
const throttleHandle = _throttle(function () {
  inputText.value = textareaRef.value.innerText
  handleSend()
}, 2000)
// 换行
const keydownEnter = (event) => {
  const div = textareaRef.value
  // 返回一个 Selection 对象，表示用户选择的文本范围或光标的当前位置
  const selection = window.getSelection() as Recordable
  // 返回一个包含当前选区内容的区域对象。
  const range = selection.getRangeAt(0)
  // startOffset：开始偏移量，选定文本的第一个字符在文本输入字段中的位置
  if (range.startOffset === range.endOffset && range.startOffset === div.textContent.length) {
    const newline = document.createElement('br')
    div.appendChild(newline)
    // 搞两个br是为了在文字末尾换行时 要点击两次的问题
    const newline2 = document.createElement('br')
    div.appendChild(newline2)
    // 该方法将选定文本的开始位置设置为给定节点之后
    range.setStartAfter(newline)
    // range.collapse(true)
    event.preventDefault()
  } else if (event.ctrlKey) {
    // 如果按下 Ctrl 键
    const newline = document.createElement('br')
    range.insertNode(newline)
    range.collapse(false)
    event.preventDefault()
  }
}
// const getFile = (e) => {
//   const file = e.target.files[0]
//   const url = window.URL.createObjectURL(file)
//   emit('handleSend', {
//     component: file.type.startsWith('image/') ? 'ImgMessage' : 'FileMessage',
//     messageProps: {
//       url,
//       // type: file.type.startsWith('image/') ? 'image' : 'file',
//       fileName:
//         file.name.length > 25 ? `${file.name.slice(0, 10)}...${file.name.slice(-15)}` : file.name,
//       fileSize: `${file.size / 1000}k`
//     }
//   })
//   e.target.value = ''
// }
const handleMousedown = () => {
  recording.value = true
  recordingTime.value = Date.now()
}
const handleMouseup = () => {
  if (Date.now() - recordingTime.value < 500) {
    recording.value = false
    messageVisible.value = true
    messageOption.value = {
      text: '语音时间太短',
      type: 'warning'
    }
  }
  // 抬起时一秒后直接结束
  setTimeout(() => {
    recording.value = false
  }, 1000)
}
// 转写完成事件
const recordingComplete = (text) => {
  recording.value = false

  if (!text) {
    messageVisible.value = true
    messageOption.value = {
      text: '未识别到内容',
      type: 'warning'
    }
    return
  }
  emit('handleSend', text)
}
</script>

<style lang="less" scoped>
.chat-input {
  padding: 8px 12px 24px;

  &-items {
    display: flex;
    margin-bottom: 8px;

    .img-box {
      background: #fff;
      border-radius: 6px;
      width: 28px;
      height: 28px;
      margin-right: 8px;
      display: flex;
      justify-content: center;
      align-items: center;
    }

    .item {
      height: 28px;
      padding: 4px 8px;
      background: #fff;
      border-radius: 6px;
      box-shadow: 0px -2px 8px 0px rgba(16, 108, 199, 0.08);

      font-size: 12px;
      font-weight: 400;
      color: #333333;
      line-height: 20px;
      text-shadow: 0px -2px 8px 0px rgba(16, 108, 199, 0.08);
      cursor: pointer;

      & + .item {
        margin-left: 8px;
      }
    }
  }

  &-box {
    display: flex;
    align-items: flex-end;
    > div {
      margin-left: 8px;
      &:first-child {
        margin-left: 0;
      }
    }

    &-main {
      flex: 1;
      background-color: #fff;
      display: flex;
      justify-content: space-between;
      align-items: center;
      flex-wrap: wrap;
      padding: 0 8px 0 12px;
      border-radius: 6px;
      overflow: hidden;
      // 录音状态下 样式需切换
      &.is-recording {
        background-color: transparent;
        padding: 0;
        .upload-box {
          margin-left: 8px;
          .img-box {
            width: 42px;
          }
        }
      }
      .textarea-box {
        // 设置最小值 多了自动撑开 单独一行
        min-width: calc(100% - 50px);
        position: relative;
        min-height: 32px;
        user-select: none;
        .textarea-content {
          height: 32px;
          line-height: 32px;
          color: #999;
          position: absolute;
          left: 0;
          top: 0;
          pointer-events: none;
        }
        &-input {
          width: 100%;
          height: 100%;
          background-color: #fff;
          word-break: break-all;
          white-space: pre-wrap;
          line-height: 20px;
          padding: 4px;
          max-height: 108px;
          min-height: 32px;
          overflow: auto;
          -webkit-user-modify: read-write-plaintext-only;
          user-select: none;
          &:focus {
            & + .textarea-content {
              display: none;
            }
          }
        }
      }

      .send {
        align-self: flex-end;
        width: 42px;
        height: 42px;
        display: flex;
        justify-content: center;
        align-items: center;
        cursor: pointer;
        img {
          width: 34px;
          height: 34px;
        }
      }
      .recording {
        //width: calc(100% - 110px);
        width: 100%;
        height: 42px;
        display: flex;
        justify-content: center;
        align-items: center;
        background-color: #fff;
        border-radius: 6px;
      }
    }
    .img-box {
      position: relative;
      width: 42px;
      height: 42px;
      background-color: #fff;
      border-radius: 6px;
      display: flex;
      justify-content: center;
      align-items: center;
      cursor: pointer;
      .svg-icon {
        width: 24px;
        height: 24px;
      }
      input {
        display: block;
        width: 24px;
        height: 24px;
        position: absolute;
        left: 4px;
        top: 9px;
        opacity: 0;
      }
    }
    .upload-box {
      // 输入内容过多时 单独一行
      flex: 1;
      background-color: #fff;
      display: flex;
      justify-content: right;
      border-radius: 6px;
      align-self: flex-end;
      .img-box {
        width: 32px;
      }
    }
  }
}
</style>
