<template>
  <div class="touch-interaction-wrap">
    <div class="title">触控交互</div>
    <div class="chat-warp scrollable">
      <template v-if="chatList.length>0">
        <div class="item" v-for="item in chatList" :class="{'is-me': item.isMe}">

          <!-- 我发的-->
          <template v-if="item.isMe">
            <el-image
                v-if="item.meImgUrl"
                style="width: 100px; height: 100px;cursor: pointer;border-radius: 8px"
                :src="item.meImgUrl"
                @click="maskImg(false,[],item.meImgUrl)"
                fit="contain"
            />
            <div class="content" v-if="item.meContent">
              {{ item.meContent }}
            </div>
            <!--            <div class="avatar">-->
            <!--              <img :src="MyAvatar" alt="" style="width: 40px;height: 40px">-->
            <!--            </div>-->
          </template>

          <!-- 回复的-->
          <template v-else>
            <div class="avatar">
              <img :src="MyAvatar" alt="" style="width: 40px;height: 40px">
            </div>
            <div class="content" v-if="item.aiContent">
              {{ item.aiContent }}
              <el-icon v-if="item.isLoading">
                <RefreshRight/>
              </el-icon>
            </div>
            <el-image
                @click="maskImg(true,item.aiPoint,item.aiImgUrl)"
                v-if="item.aiImgUrl"
                style="width: 100px; height: 100px;cursor: pointer;border-radius: 8px"
                :src="item.aiImgUrl"
                fit="contain"
            />
          </template>
        </div>
      </template>
      <template v-else>
        <div class="empty">
          <div class="flex align-center">
            <img :src="MyAvatar" alt="" style="width: 40px;height: 40px;margin-right:  10px">
            <div class="content">我是你的触控交互助手，很高兴见到你！</div>
          </div>
          <div class="desc">请把你需要识别的图片交给我吧~</div>
        </div>
      </template>
    </div>

    <img id="sourceImage" :src="currentCanvasUrl" alt="Source Image" style="display: none;">
    <canvas id="canvas" v-show="openPre"></canvas>

    <div class="actions">
      <el-upload
          :auto-upload="false"
          v-model:file-list="fileList"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
          :limit="1"
      >
        <template #trigger>
          <el-button type="primary">select file</el-button>
        </template>
      </el-upload>
      <el-input :disabled="enableInput" type="textarea"
                :autosize="{ minRows: 5, maxRows: 7 }"
                placeholder="输入你的问题并上传图片"
                v-model="chatVal"
      >
      </el-input>
      <div class="btn-wrap">
        <input type="file" id="hiddenFileInput" style="display: none;" accept="image/*"/>
        <el-tooltip
            effect="dark"
            content="上传附件"
            placement="top-start"
        >
          <!-- 隐藏的文件输入元素 -->
          <div class="attachment flex align-center justify-content-center" @click="handleAttachmentClick">
            <el-button circle :disabled="enableInput">
              <template #icon>
                <el-icon :size="20">
                  <Paperclip/>
                </el-icon>
              </template>
            </el-button>
          </div>
        </el-tooltip>

        <el-tooltip
            effect="dark"
            :content="`${chatVal!==''&&fileList.length!==0?'发送':'请输入你的问题并上传图片'}`"
            placement="top-start"
        >
          <div class="submit flex align-center justify-content-center" @click="sendText">
            <el-button type="primary" circle :disabled="!enableInput&&chatVal===''||fileList.length===0">
              <template #icon>
                <el-icon :size="20">
                  <Top/>
                </el-icon>
              </template>
            </el-button>
          </div>
        </el-tooltip>
      </div>
    </div>
  </div>
  <el-dialog v-model="dialogVisible" :show-close="false">
    <img :src="dialogImageUrl" alt="Preview Image" style="height: 50vh;max-width: 50vw"/>
  </el-dialog>
</template>

<script setup>
import {Paperclip, Plus, RefreshRight, Top} from "@element-plus/icons-vue";
import {ElMessage} from 'element-plus'
import {coordinateMarking} from "@/api/touch_interaction.js";
import AiAvatar from "./ai.png"
import MyAvatar from "./zsj.png"

const item = {
  isMe: false,
  meImgUrl: "",
  meContent: "",
  isLoading: false,
  aiImgUrl: "",
  aiContent: "",
  aiPoint: []
}
const chatList = ref([])//会话列表
const fileList = ref([])//文件列表
const chatVal = ref("") //文本
const enableInput = ref(false) //允许上传和输入

// name: file.name,
// url: e.target.result,
// fileObj: file
const currentMaskFile = ref(null)
const currentCanvasUrl = ref(null)

const dialogVisible = ref(false) //文件预览
const dialogImageUrl = ref("") //文件预览的url

const markFormData = new FormData()//带上传的formData

const openPre = ref(false)

const addMeContent = (content) => {
  chatList.value.push({
    isMe: true,
    meImgUrl: "",
    meContent: content,
    isLoading: false,
    aiImgUrl: "",
    aiContent: "",
    aiPoint: []
  })
}
const addMeUrl = (url) => {
  chatList.value.push({
    isMe: true,
    meImgUrl: url,
    meContent: "",
    isLoading: false,
    aiImgUrl: "",
    aiContent: "",
    aiPoint: []
  })
}
const addAiContent = (content, loading = false) => {
  chatList.value.push({
    isMe: false,
    meImgUrl: "",
    meContent: "",
    isLoading: loading,
    aiImgUrl: "",
    aiContent: content,
    aiPoint: []
  })
}
const addAiUrl = (url, point) => {
  chatList.value.push({
    isMe: false,
    meImgUrl: "",
    meContent: "",
    isLoading: false,
    aiImgUrl: url,
    aiContent: "",
    aiPoint: point
  })
}


const sendText = () => {
  enableInput.value = true
  if (!chatVal.value) {
    ElMessage({
      message: '请输入内容',
      type: 'warning',
    })
    return
  }
  currentMaskFile.value = fileList.value[0]
  markFormData.append("words", chatVal.value)
  markFormData.append("image", fileList.value[0]['fileObj'])
  addMeUrl(fileList.value[0]['url'])
  addMeContent(chatVal.value)
  addAiDynamicContent("正在思考中...", true)
  chatVal.value = ""
  fileList.value = []
  scrollEnd();
  coordinateMarking(markFormData).then((res) => {
    const msg = JSON.parse(res.msg)
    if (Array.isArray(msg)) {
      chatList.value.pop()
      addAiContent(res.msg) // 坐标数据
      addAiUrl(currentMaskFile.value['url'], msg)
    } else {
      addAiContent(msg)
    }
  }).catch((err) => {
    console.log(err)
    chatList.value.pop()
    addAiDynamicContent("识别超时，请稍后重试")
  })
      .finally(() => {
        chatList.value[chatList.value.length - 1]['content'] = ""
        markFormData.delete("image")
        markFormData.delete("words")
        const newInput = document.createElement('input');
        const input = document.getElementById("hiddenFileInput");
        newInput.type = 'file';
        newInput.id = 'hiddenFileInput';
        newInput.accept = "image/*"
        newInput.style.display = 'none';
        input.parentNode.replaceChild(newInput, input);
        scrollEnd();
        enableInput.value = false
      })
};

const handleAttachmentClick = () => {
  const input = document.getElementById("hiddenFileInput");
  input.click();
  // 移除所有现有的change事件监听器
  input.removeEventListener("change", handleFileChange);
  input.addEventListener("change", handleFileChange)
};

const handleFileChange = (event) => {
  const file = event.target.files[0];
  if (file) {
    // 创建FileReader对象
    const reader = new FileReader();
    // 读取完成后触发的事件处理程序
    reader.onload = e => {
      // 更新ref
      fileList.value = [{
        name: file.name,
        url: e.target.result,
        fileObj: file
      }];
    };
    // 以DataURL的形式读取文件内容
    reader.readAsDataURL(file);
  }
}

const handlePictureCardPreview = (uploadFile) => {
  dialogVisible.value = true
  dialogImageUrl.value = fileList.value[0]['url']
}

const maskImg = (draw, [x1, y1, x2, y2], url) => {
  openPre.value = true
  const canvas = document.getElementById('canvas');
  const ctx = canvas.getContext('2d');
  const sourceImage = document.getElementById('sourceImage');
  sourceImage.src = url
  canvas.addEventListener('click', () => {
    openPre.value = false
  })
  // 设置canvas大小与图片大小相同
  canvas.width = sourceImage.width;
  canvas.height = sourceImage.height;
  console.log(x1, y1, x2, y2, url)
  // 绘制图片到canvas
  ctx.drawImage(sourceImage, 0, 0);

  if (draw) {
    // 定义坐标和矩形大小
    const x = x1; // 矩形左上角x坐标
    const y = y1; // 矩形左上角y坐标
    const width = Math.abs(x2 - x1); // 矩形宽度绝对值
    const height = Math.abs(y2 - y1); // 矩形高度

    // 绘制矩形
    ctx.strokeStyle = 'red'; // 矩形边框颜色
    ctx.lineWidth = 10; // 矩形边框宽度
    ctx.strokeRect(x, y, width, height); // 绘制矩形
  }
}

//删除还未上传的图片
const handleRemove = (uploadFile, uploadFiles) => {
  fileList.value = []
}

//滚动条滚动到最底部
const scrollEnd = () => {
  setTimeout(() => {
    const box = document.querySelector(".chat-warp");
    if (box) {
      box.scrollTo({top: box.scrollHeight, behavior: "smooth"});
    }
  }, 100);
};
watch(
    () => chatList.value,
    () => {
      scrollEnd();
    }
);

const addAiDynamicContent = (content, loading = false) => {
  chatList.value.push({
    isMe: false,
    meImgUrl: "",
    meContent: "",
    isLoading: false,
    aiImgUrl: "",
    aiContent: "",
    aiPoint: []
  })
  const words = content.split("")
  for (let i = 0; i < words.length; i++) {
    setTimeout(() => {
      chatList.value[chatList.value.length - 1]['aiContent'] += words[i]
    }, i * 200 + Math.random() * 100)
  }
  if (loading) {
    chatList.value[chatList.value.length - 1]['isLoading'] = true
  }
}
</script>

<style scoped lang="scss">
.touch-interaction-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;

  .add {
    position: fixed;
    top: 0;
    left: 0;
  }

  .empty {
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;

    .content {
      font-size: 24px;
    }

    .desc {
      font-size: 14px;
      color: #404040;
      margin-top: 8px;
    }
  }

  .title {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 800px;
    height: 46px;
    margin-top: 10px;
    font-size: 16px;
    color: #262626;
    font-weight: 600;
    border-radius: 12px;
    box-shadow: inset 0 0 0 1px rgb(229, 229, 229);
  }

  .chat-warp {
    width: 800px;
    height: calc(100vh - 340px); //220 56
    overflow-y: auto;
    padding-top: 20px;

    .item {
      display: flex;
      align-items: center;
      margin-bottom: 16px;
      padding-right: 10px;

      img {
        width: 28px;
        height: 28px;
        margin-right: 20px;
      }

      .content {
        font-size: 16px;
        line-height: 28px;
        color: #262626;
        padding: 8px 20px;
        box-sizing: border-box;
        white-space: pre-wrap;
        word-break: break-word;
        background-color: #eff6ff;
        border-radius: 14px;
        max-width: calc(100% - 48px);
        display: flex;
        align-items: center;

        i {
          margin-left: 2px;
          animation: spin 1.5s linear infinite;
        }

        @keyframes spin {
          from {
            transform: rotate(0deg);
          }
          to {
            transform: rotate(360deg);
          }
        }

      }

      &.is-me {
        justify-content: flex-end;

        .content {
          margin-left: 0;
        }

        img {
          margin-left: 20px;
        }
      }
    }
  }

  .actions {
    width: 800px;
    position: relative;

    :deep(.el-textarea__inner ) {
      padding: 10px 20px;
      background-color: rgb(243, 244, 246);
      border-radius: 24px;
      box-shadow: 0 0 0 .5px #dce0e9;
      color: rgb(64, 64, 64);
      font-size: 16px;

      &::-webkit-scrollbar {
        width: 0;
        height: 0;
      }
    }

    :deep(.el-upload--picture-card ) {
      display: none;
    }

    :deep(.el-upload-list__item ) {
      height: 80px;
      width: auto;
    }

    .btn-wrap {
      position: absolute;
      right: 20px;
      bottom: 10px;
      display: flex;

      .attachment {

        margin-right: 10px;

      }

      .submit {
      }
    }
  }

  #canvas {
    position: fixed;
    z-index: 99999999;
    width: 100vw;
    height: 100vh;
  }
}
</style>
