<template>
  <div class="ai-layout" :class="{ 'is-mobile': isMobile }">
    <div
      class="open-chat"
      :class="{
        'toggle-off': isOpen,
        'toggle-on': !isOpen
      }"
      @click="toggleChatOpen('open')"
    >
      <img
        src="./img/layout/ai-figure-base.png"
        alt=""
        :class="{ 'is-drag': isDrag }"
        @dragstart.prevent
      />
      <div class="open-tip">
        <div class="hi"> HI，我是AI机器人，有什么想要了解的可以问我哦 </div>
      </div>
    </div>
    <div class="chat-container" :class="[isOpen ? 'show' : 'hide', isExpand ? 'is-expand' : '']">
      <div class="chat-bg"></div>
      <div class="chat-topbar">
        <div class="chat-topbar-text" v-if="!isMobile" @dragstart.prevent>AI机器人</div>
        <!-- 移动端下顶部的ai图片部分 -->
        <template v-if="isMobile">
          <!-- web是右上角关闭按钮 H5是左上角回退按钮 -->
          <img
            src="./img/icon/back.png"
            class="close-back"
            alt=""
            @click="toggleChatOpen('close')"
          />
        </template>
        <div class="chat-topbar-operates">
          <div class="chat-topbar-operates_icon newChat" @click="handleNewChat">+新对话</div>
          <div class="chat-topbar-operates_icon" @click="handleExpand">
            <img alt="" v-if="isExpand" src="./img/icon/contract.png" />
            <img alt="" v-else src="./img/icon/expand.png" />
          </div>
          <div v-if="!isMobile" class="chat-topbar-operates_icon" @click="toggleChatOpen">
            <img alt="" src="./img/icon/close.png" />
          </div>
        </div>
      </div>
      <div class="chat-main">
        <div class="chat-figure">
          <img src="./img/layout/ai-figure-base.png" alt="" @dragstart.prevent />
        </div>
        <div class="chat-window">
          <AiChat
            class="chat-content"
            ref="AiChatRef"
            :is-open="isOpen"
            @handle-send="handleSend"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import AiChat from './components/AiChat.vue'
import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue'

const props = defineProps({
  a: {
    type: Boolean,
    default: false
  }
})

console.log('props', props)

const isOpen = ref(false)
const isExpand = ref(false)

const isMobile = computed(() => /Mobile/i.test(navigator.userAgent))

const isDrag = ref(false) // 用于在拖拽过程中 隐藏logo tip

// 记录聊天框的鼠标点击处的位置，用于在下面move方法中处理拖拽边界问题上的计算
const chatBarClickPos: Recordable = ref({})

onMounted(() => {
  nextTick(() => {
    const aiLogoBox = document.querySelector('.open-chat') as HTMLElement

    if (isMobile.value) {
      // 防冒泡
      aiLogoBox.addEventListener('touchstart', (e) => {
        const pageX = e.touches[0].pageX
        const pageY = e.touches[0].pageY
        chatBarClickPos.value = {
          right: aiLogoBox.offsetWidth - (pageX - aiLogoBox.offsetLeft),
          bottom: aiLogoBox.offsetHeight - (pageY - aiLogoBox.offsetTop)
        }
        isDrag.value = false
        aiLogoBox.addEventListener('touchmove', mouseMove)
      })
      aiLogoBox.addEventListener('touchend', () => {
        aiLogoBox.removeEventListener('touchmove', mouseMove)
      })
      isDrag.value = false
    } else {
      aiLogoBox.addEventListener('mousedown', (e) => {
        chatBarClickPos.value = {
          right: aiLogoBox.offsetWidth - e.offsetX,
          bottom: aiLogoBox.offsetHeight - e.offsetY
        }

        isDrag.value = false
        document.addEventListener('mousemove', mouseMove)
      })
      document.addEventListener('mouseup', () => {
        document.removeEventListener('mousemove', mouseMove)
        setTimeout(() => {
          isDrag.value = false
        }, 100)
      })
    }
  })
})

onUnmounted(() => {
  const aiLogoBox = document.querySelector('.open-chat img') as HTMLElement
  if (isMobile.value) {
    aiLogoBox && aiLogoBox.removeEventListener('touchend', () => {})
    // document.body.removeEventListener('touchend', () => {})
  } else {
    document.removeEventListener('mouseup', () => {})
  }
})

const mouseMove = (e) => {
  // 可视区宽度
  const clientWidth = document.body.clientWidth
  const clientHeight = document.body.clientHeight

  const pageX = isMobile.value ? e.touches[0].pageX : e.pageX
  const pageY = isMobile.value ? e.touches[0].pageY : e.pageY

  // 拖拽过程中 隐藏tip，并点击抬起后不打开聊天框
  isDrag.value = true

  const aiLogoBox = document.querySelector('.open-chat') as HTMLElement
  // 处理边界问题
  const r = clientWidth - pageX - chatBarClickPos.value.right
  aiLogoBox.style.right = `${r < 0 ? 0 : r > clientWidth - aiLogoBox.offsetWidth ? clientWidth - aiLogoBox.offsetWidth : r}px`
  const b = clientHeight - pageY - chatBarClickPos.value.bottom
  aiLogoBox.style.bottom = `${b < 0 ? 0 : b > clientHeight - aiLogoBox.offsetHeight ? clientHeight - aiLogoBox.offsetHeight : b}px`
}
// 打开关闭弹窗
const toggleChatOpen = (type) => {
  if (isDrag.value) return

  isOpen.value = type === 'open'
}
// 展开收起
const handleExpand = () => {
  isExpand.value = !isExpand.value
}

const AiChatRef = ref()
const handleNewChat = () => {
  AiChatRef.value.newChat()
}

// 发送消息
const emit = defineEmits(['on-handle-send'])
const handleSend = (message) => {
  emit('onMessage', message)
}
// 接受消息
const handleResponse = (message) => {
  AiChatRef.value?.handleMessageResponse(message)
}
defineExpose({ handleResponse })
</script>

<style lang="less">
@import './styles/variables.less';
@import './styles/index.less';
// 移动端下点击的高亮
.ai-layout * {
  -webkit-tap-highlight-color: transparent;
}
.chat-container {
  position: fixed;
  bottom: 0;
  right: 0;
  width: 680px;
  height: 680px;
  max-height: 90%;
  z-index: 101;
  font-size: 14px;
  transform: scale(0);
  transform-origin: right bottom;
  display: flex;
  flex-direction: column;
  align-items: center;
  transition:
    width 0.5s,
    height 0.5s;

  // 移动端默认字体16px
  //.is-mobile & {
  //  font-size: 16px;
  //  line-height: 24px;
  //}
  .chat-bg {
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
    background-image: url('img/layout/chat-bg.jpg');
    background-color: transparent;
    background-repeat: no-repeat;
    background-size: 100% auto;
    box-shadow: 2px 2px 10px 2px rgba(0, 0, 0, 0.1);
    overflow: hidden;
    border-radius: 12px;
  }
  .chat-topbar {
    height: 52px;
    width: 100%;
    flex-shrink: 0;
    z-index: 1;

    display: flex;
    justify-content: space-between;
    align-items: center;
    &-text {
      font-size: 20px;
      font-weight: bold;
      color: #fff;
      margin-left: 100px;
    }
    &-operates {
      display: flex;
      margin-right: 10px;
      &_icon {
        margin-right: 8px;
        width: 26px;
        height: 26px;
        background-color: #fff;
        border-radius: 6px;
        box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.08);
        display: flex;
        justify-content: center;
        align-items: center;
        cursor: pointer;
        color: #666;
        &.newChat {
          width: auto;
          padding: 0 8px;
        }
      }
    }
  }
  .chat-main {
    flex: 1;
    width: 100%;
    height: calc(100% - 52px);
    display: flex;
    .chat-figure {
      width: 90px;
      height: 100px;
      position: absolute;
      left: 0;
      top: -30px;
      overflow: hidden;
      text-align: center;
      img {
        width: 80%;
      }
    }
    .chat-window {
      flex: 1;
      display: flex;
      flex-direction: column;
      width: 100%;
      height: 100%;
      border-radius: 8px;
      overflow: hidden;
      .chat-content {
        position: relative;
        overflow: auto;
        width: 100%;
        flex: 1;
      }
    }
  }
  &:not(.is-expand) {
    .chat-content-ai {
      background: linear-gradient(180deg, rgba(235, 239, 248, 0.56), #ebeff8);
      border: 1px solid;
      border-image: linear-gradient(180deg, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0)) 1 1;
      backdrop-filter: blur(4px);
    }
  }
  &.is-expand {
    width: 90%;
    max-width: 1200px;
    height: 90%;
    max-height: 900px;
    // 展开时 样式
    //overflow: hidden;
    border-radius: 16px;
    .chat-topbar {
      &-ai {
        display: none;
      }
      &-text {
        margin-left: 30px;
        font-size: 28px;
      }
    }
    .chat-main {
      .chat-figure {
        width: 376px;
        display: flex;
        justify-content: center;
        align-items: center;
        position: static;
        height: auto;
        margin-bottom: 100px;
        z-index: 99;
        img {
          width: 100%;
        }
      }
    }
  }
  &.show {
    animation: scaleIn 0.15s ease-in-out 0s 1 normal forwards;
  }
  &.hide {
    display: none;
  }
}

.is-mobile .chat-container {
  bottom: 0;
  right: 0;
  width: 100%;
  height: 100%;
  max-height: 100%;
  .chat-bg {
    background-image: url('img/layout/chat-bg-h5.jpg');
  }
  .chat-topbar {
    height: 56px;
    position: absolute;
    left: 0;
    top: 12px;
    z-index: 100;
    display: flex;
    justify-content: space-between;
    .close-back {
      margin-left: 22px;
    }
  }
  .chat-main {
    position: relative;
    width: 100%;
    height: 100%;
    .chat-figure {
      width: 100%;
      display: flex;
      justify-content: center;
      align-items: flex-start;
      position: static;
      height: auto;
      img {
        width: 24%;
        transition: width 0.5s;
        margin-top: 20px;
      }
    }
    .chat-window {
      position: absolute;
      bottom: 0;
      left: 0;
      z-index: 99;
      width: 100%;
      height: calc(100% - 130px);
      transition: height 0.5s;
      border-radius: 16px 16px 0 0;
      box-shadow: 0px -3px 10px 0px rgba(0, 0, 0, 0.06);
      overflow: hidden;
      .chat-content-ai {
        border: none;
      }
    }
  }
  &.is-expand {
    .chat-figure {
      img {
        width: 64%;
      }
    }
    .chat-window {
      height: calc(100% - 354px);
      min-height: 66%;
      backdrop-filter: blur(10px);
    }
  }
}

.open-chat {
  position: fixed;
  width: 60px;
  right: 30px;
  bottom: 200px;
  cursor: pointer;
  z-index: 101;
  transform: scale(0);
  .is-mobile & {
    width: 60px;
    right: 10px;
    bottom: 100px;
    .open-tip {
      display: none !important;
    }
  }
  img {
    width: 100%;
    transition: all 0.5s;
    position: relative;
    z-index: 99;
    &:not(.is-drag):hover + .open-tip {
      display: block;
      animation: scaleIn 0.15s ease-in-out 0.15s 1 normal forwards;
    }
    // 拖动过程中隐藏
    &:has(.is-drag) {
      display: none;
    }
  }
  .open-tip {
    position: absolute;
    right: -4px;
    top: 22px;
    z-index: 98;
    width: 236px;
    font-size: 14px;
    font-weight: 600;
    color: #315e97;
    padding: 12px 64px 12px 16px;
    background: linear-gradient(180deg, #dbf1ff, #ffffff);
    border: 1px solid;
    border-image: linear-gradient(360deg, rgba(255, 255, 255, 0), #ffffff) 1 1;
    border-radius: 8px;
    box-shadow: 0px 4px 20px 0px rgba(76, 107, 148, 0.15);
    display: none;
    transform: scale(0);
    transform-origin: top right;
    &:hover {
      display: block;
      animation: scaleIn 0.15s ease-in-out 0.15s 1 normal forwards;
    }
    .hi {
      color: #1d80ff;
      line-height: 26px;
      & + div {
        width: 120px;
        text-align: justify;
        text-align-last: justify;
      }
    }
  }
  &.toggle-off {
    display: none;
  }
  &.toggle-on {
    animation: scaleIn 0.15s ease-in-out 0.15s 1 normal forwards;
  }
}

@keyframes scaleIn {
  0% {
    transform: scale(0);
  }
  100% {
    transform: scale(1);
  }
}
</style>
