<template>
  <p v-if="!messages.length" class="text-muted-color text-center m-auto">
    Chat is empty
  </p>

  <PrimeScrollPanel v-else ref="scroll" class="flex-1 min-h-0 overflow-x-hidden">
    <div class="flex flex-col gap-3">
      <div
        v-for="message in messages"
        :key="message.id"
        class="w-fit max-w-[60%]"
        :class="{
          'ml-auto': message.sender === me?.username,
        }"
      >
        <p
          v-if="message.sender !== me?.username"
          class="text-sm text-muted-color mb-1"
        >
          {{ message.sender }}
        </p>

        <div
          class="px-3 py-2 rounded-lg"
          :class="{
            'bg-surface-800': message.sender !== me?.username,
            'bg-surface-700': message.sender === me?.username,
          }"
        >
          <p class="[&>a]:break-all" @click="handleMessageClick" v-html="parseMessageText(message.text)" />

          <p class="mt-1 text-right text-sm text-muted-color" :title="formatDate(message.createdAt, 'dd.MM.yyyy, HH:mm')">
            {{ formatDate(message.createdAt) }}
          </p>
        </div>
      </div>
    </div>
  </PrimeScrollPanel>

  <div class="mt-3 shrink-0">
    <PrimeInputGroup>
      <!--      <PrimeInputGroupAddon> -->
      <!--        <PrimeButton severity="secondary" class="shrink-0" disabled> -->
      <!--          <template #icon> -->
      <!--            <Paperclip /> -->
      <!--          </template> -->
      <!--        </PrimeButton> -->
      <!--      </PrimeInputGroupAddon> -->

      <PrimeInputText
        ref="input"
        v-model="text"
        placeholder="Write a message..."
        fluid
        autocomplete="off"
        @keydown.enter.exact="sendMessage"
        @vue:mounted="onInputMounted"
      />

      <PrimeButton class="shrink-0" label="Send" severity="contrast" :disabled="!text" @click="sendMessage" />
    </PrimeInputGroup>
  </div>
</template>

<script setup lang="ts">
import { useEventBus } from '#imports'
import { onStartTyping, unrefElement, useEventListener } from '@vueuse/core'
import { format } from 'date-fns'
import linkifyStr from 'linkify-string'
import { useChat } from '~/composables/use-chat'

definePageMeta({
  name: 'Index',
})

const { openUrl } = useApp()
const { me } = useClients()
const chat = useChat()
const eventBus = useEventBus()
const { messages } = chat

const scrollRef = useTemplateRef('scroll')
const inputRef = useTemplateRef('input')
const contentRef = computed(() => scrollRef.value?.$refs.content)

const text = ref('')

eventBus.on('chat:new-message', onNewMessage)

onScopeDispose(() => {
  eventBus.off('chat:new-message', onNewMessage)
})

function parseMessageText(text: string) {
  return linkifyStr(
    text,
    {
      className: 'underline',
      rel: 'noopener noreferrer',
      target: '_blank',
    },
  ).replaceAll('\n', '<br>')
}

function formatDate(date: string, formatStr = 'HH:mm') {
  return format(date, formatStr)
}

function sendMessage() {
  if (!text.value)
    return

  chat.sendMessage({
    text: text.value,
  })

  text.value = ''
}

function onInputMounted(ref: VNode) {
  ref.el?.focus()
}

useEventListener(window, 'focus', async (evt) => {
  unrefElement(inputRef.value)?.focus()
})

onStartTyping(() => {
  unrefElement(inputRef.value)?.focus()
})

const ARRIVED_STATE_THRESHOLD_PIXELS = 1
async function onNewMessage() {
  if (!contentRef.value)
    return

  const arrivedBottom = contentRef.value.scrollTop + contentRef.value.clientHeight
    >= contentRef.value.scrollHeight - ARRIVED_STATE_THRESHOLD_PIXELS

  const scrollable = contentRef.value.scrollHeight > contentRef.value.clientHeight

  await nextTick()

  if (scrollable && !arrivedBottom)
    return

  contentRef.value.scrollTo({
    behavior: 'smooth',
    top: contentRef.value.scrollHeight,
  })
}

function handleMessageClick({ target }: MouseEvent) {
  if (!target)
    return

  if (target instanceof HTMLElement) {
    if (target.tagName === 'A') {
      target.addEventListener('click', onAnchorClick)
    }
  }
}

function onAnchorClick(event: MouseEvent) {
  event.preventDefault()

  const target = event.target as HTMLAnchorElement

  console.log('yo')
  openUrl(target.href)
}
</script>
