<script lang="ts">
import { ref, type Ref } from 'vue'
import BadgeVue from './ChatBadge.vue'
import { getBadges } from '@/assets/badges'
import { parseMessage } from '@/assets/messageParser'
import type { Badge, ParsedMessage } from '@/assets/types'

export default {
  props: {
    isLive: {
      type: Boolean,
      default() {
        return false
      }
    },
    channelName: {
      type: String
    }
  },
  async setup(props) {
    let messages: Ref<ParsedMessage[]> = ref([])
    const protocol = import.meta.env.VITE_HTTPS === 'true' ? 'https://' : 'http://'
    
    const badgesFetch = await fetch(`${protocol}${import.meta.env.VITE_BACKEND_DOMAIN}/api/badges?channelName=${props.channelName}`)
    let badges: Badge[] =  (await badgesFetch.json()).data

    return {
      ws: new WebSocket(`ws://${import.meta.env.VITE_BACKEND_DOMAIN}`),
      messages,
      badges,
      props,
    }
  },
  mounted() {
    const chatList = this.$refs.chatList as Element
    const chatStatusMessage = this.$refs.initConnectingStatus as Element

    this.ws.onmessage = (message) => {
      if (message.data == 'OK') {
        chatStatusMessage.textContent = `Connected to ${this.channelName}`
      } else {
        this.messages.push(parseMessage(message.data, this.badges))
        this.clearMessages()
        this.scrollToBottom(chatList)
      }
    }

    this.ws.onopen = () => {
      this.ws.send('JOIN ' + this.props.channelName?.toLowerCase())
    }
  },
  methods: {
    getChat() {
      return this.messages
    },
    scrollToBottom(el: Element) {
      el.scrollTop = el.scrollHeight
    },
    clearMessages() {
      if (this.messages.length > 50) {
        this.messages.shift()
      }
    },
    getBadges(message: ParsedMessage) {
      let badgesString = message.data.tags.badges;
      if (!badgesString) return;
      let badges = badgesString.split(',');
      let formatedBadges = badges.map((badgeWithVersion: string) => {
        const [setId, version] = badgeWithVersion.split('/');
        return { setId, version };
      });

      return getBadges(this.badges, formatedBadges);
    }
  },
  components: {
    BadgeVue
  },
  unmounted() {
    this.messages = []
    this.badges = []
  }
}
</script>
<template>
  <div v-if="isLive" class="p-3 bg-ctp-crust rounded-lg w-full max-w-[15.625rem] flex flex-col">
    
    <!-- SYSTEM MESSAGES -->
    <ul
      class="overflow-y-scroll overflow-x-hidden space-y-1 whitespace-pre-wrap h-[46.875rem]"
      ref="chatList"
    >
      <li>
        <p ref="initConnectingStatus" class="text-gray-500 text-sm italic">
          Connecting to {{ channelName }}.
        </p>
      </li>
      <li v-for="message in getChat()" :key="messages.indexOf(message)">

        <div v-if="message.type === 'PRIVMSG'" class="text-white inline-flex">
          
          <!-- CHAT MESSAGE-->
          <p class="text-sm items-center">

            <ul class="inline-flex space-x-1 pr-1">
              <li v-for="badge in getBadges(message)" :key="badge.id">
                <badge-vue :badge-info="badge"></badge-vue>
              </li>
            </ul>
            
            <strong
              :style="message.data.tags.color ? `color: ${message.data.tags.color};` : ``"
              class="text-ctp-pink font-bold">
              {{ message.data.username }}</strong>: {{ message.data.message }}
          </p>
        </div>

        <div v-else-if="message.type === 'CLEARMSG'" class="text-white inline-flex">
          <p class="text-sm text-gray-500 italic"> Message by {{ message.data.username }} removed </p>
        </div>

        <div v-else class="text-white">
          {{ message }}
        </div>
      </li>
    </ul>
  </div>
</template>
