<script setup>
import {ref} from "vue";
import {ElMessage} from "element-plus";
import {util, MessageType} from "./Util.js";

let messages = ref({})
let message = ref('')
let status = ref("未连接")
let raw = ref("")
let key = ""
let waitTimer = ref(0)
let waitIntervalId = 0

let purgeOnDisconnect = false
let deleteTimer = 0
let counter = 0
let websocket

function init(){
  if(raw.value.trim().length < 4){
    ElMessage.error("长度不够，请重新输入")
    return
  }

  key = util.generateKey(raw.value)
  let pairCode = util.generatePairCode(key)

  websocket = new WebSocket('ws://localhost:7777')
  websocket.onopen = () => {
    let initMessage = {"type": MessageType.INIT, "pairCode": pairCode}
    websocket.send(JSON.stringify(initMessage))
  }

  websocket.onmessage = (event) => {
    if(event.data.startsWith("{"))
      switch (JSON.parse(event.data).type){
        case MessageType.WAIT:
              waitTimer.value = 60
              status.value = '等待中'
              waitIntervalId = setInterval(() => {
                if(waitTimer.value > 0)
                  waitTimer.value--
                else {
                  status.value = '未连接'
                  websocket.close()
                  waitTimer.value = 0
                  ElMessage.error("已超时,请重新发起连接")
                  clearInterval(waitIntervalId)
                }
              }, 1000)
              break
        case MessageType.JOIN:
              status.value = '已连接'
              waitTimer.value = 0
              clearInterval(waitIntervalId)
              ElMessage.success("已加入聊天")
              break
        case MessageType.DISCONNECT:
              status.value = '已断开'
              ElMessage.error("对方已断开")
              if(purgeOnDisconnect)
                messages.value = {}
              break
      }
    else {
      let data = util.decrypt(event.data, key)
      data = JSON.parse(data)
      switch (data.type){
        case MessageType.PURGE_CONFIG:
              purgeOnDisconnect = data.purgeOnDisconnect
              if(purgeOnDisconnect)
                messages.value[++counter] = {'type': 'config', 'message': '对方已设置断开连接后删除消息'}
               else
                messages.value[++counter] = {'type': 'config', 'message': '对方已设置断开连接后保留消息'}
              break
        case MessageType.TIMER_CONFIG:
              deleteTimer = data.deleteTimer
              if(deleteTimer > 0)
                messages.value[++counter] = {'type': 'config', 'message': `对方已设置${deleteTimer}秒后删除消息`}
              else
                messages.value[++counter] = {'type': 'config', 'message': `对方已关闭定时删除消息`}
              break
        case MessageType.MESSAGE:
              messages.value[++counter] = {'type': 'other', 'message': data.message}
              if(deleteTimer !== 0) {
                let key = counter
                setTimeout(() => {
                  console.log("删除消息:", key)
                  delete messages.value[key]
                }, deleteTimer * 1000)
              }
              break
      }
    }

    websocket.onclose = () => {
      status.value = '已断开'
      ElMessage.error("与服务器失去连接")
      if(purgeOnDisconnect)
        messages.value = {}
    }
  }
}

function send(){
  let data = {'type': MessageType.MESSAGE, 'message': message.value}
  data = {'type': MessageType.CONTENT, 'content': util.encrypt(JSON.stringify(data), key)}
  websocket.send(JSON.stringify(data))

  messages.value[++counter] = {'type': 'self', 'message': message.value}
  if(deleteTimer !== 0) {
    let key = counter
    setTimeout(() => {
      console.log("删除消息:", key)
      delete messages.value[key]
    }, deleteTimer * 1000)
  }
  message.value = ''
}

function setDeleteTimer(sec){
  deleteTimer = sec
  let data = {'type': MessageType.TIMER_CONFIG, deleteTimer}
  data = {'type': MessageType.CONTENT, 'content': util.encrypt(JSON.stringify(data), key)}
  websocket.send(JSON.stringify(data))

  if(sec === 0)
    messages.value[++counter] = {'type': 'config', 'message': `你关闭了定时删除消息`}
  else
    messages.value[++counter] = {'type': 'config', 'message': `你设置了${sec}秒后删除消息`}
}

function setPurgeOnDisconnect(isPurge){
  purgeOnDisconnect = isPurge
  let data = {'type': MessageType.PURGE_CONFIG, purgeOnDisconnect}
  data = {'type': MessageType.CONTENT, 'content': util.encrypt(JSON.stringify(data), key)}
  websocket.send(JSON.stringify(data))

  if(isPurge)
    messages.value[++counter] = {'type': 'config', 'message': `你设置了断开连接后删除消息`}
  else
    messages.value[++counter] = {'type': 'config', 'message': `你设置了断开连接后保留消息`}
}

</script>

<template>
  <el-container>
    <el-header style="text-align: center">
      {{status}}
    </el-header>
    <el-main>
      <div v-if="status === '已连接' || status === '已断开'">
        <el-scrollbar max-height="60%">
          <div v-for="message in messages" :class="message.type">
            {{message.message}}
          </div>
        </el-scrollbar>
        <el-button @click="setDeleteTimer(10)">开启定时删除</el-button>
        <el-button @click="setDeleteTimer(0)">关闭定时删除</el-button>
        <el-button @click="setPurgeOnDisconnect(true)">设置断联删除消息</el-button>
        <el-button @click="setPurgeOnDisconnect(false)">设置断联保留消息</el-button>
        <el-input v-model="message"/>
        <el-button @click="send">发送消息</el-button>
      </div>

      <div v-if="status === '未连接'">
        请输入四到十六位字符串以生成密钥:
        <el-input v-model="raw"/>
        <el-button @click="init">连接</el-button>
      </div>
      <div v-if="status === '等待中'">
        {{waitTimer}}
      </div>
    </el-main>
  </el-container>
</template>

<style scoped>
.self{
  background: #bfa;
}

.other{
  background: red;
}

.config{
  background: gray;
}
</style>
