'use client'

import { BackButton } from '@/app/components/BackButton'
import { DiscordButton } from '@/app/components/DiscordButton'
import { GetIconForUser } from '@/util/bd'
import { getCookie } from '@/util/cookie'
import axios from 'axios'
import { useEffect, useRef, useState } from 'react'

interface WSMessage {
  success: boolean
  message: string | null
  for: string
  data: any
}

type BirdColor = [number, number, number]

interface Message {
  username: string
  userId: number
  content: string
  id: number
  icon: number
  overlay: number
  birdColor: BirdColor
  overlayColor: BirdColor
  customIcon: string | null
}

interface CustomIconEntry {
  data: string
  id: string
}

export default function BerryDashChatroom () {
  const [connected, setConnected] = useState<boolean>(false)
  const [loggedIn, setLoggedIn] = useState<boolean>(false)
  const [token, setToken] = useState<string | null>(null)
  const [messages, setMessages] = useState<Message[]>([])
  const [customIconCache, setCustomIconCache] = useState<CustomIconEntry[]>([])
  const [ws, setWs] = useState<WebSocket | null>(null)

  const messagesDiv = useRef<HTMLDivElement>(null)
  const [input, setInput] = useState<string>('')

  useEffect(() => {
    document.title = 'Lncvrt Games - Chatroom'

    const token = getCookie('accountToken', '-1')
    if (token !== '-1') {
      setLoggedIn(true)
      setToken(token)
    }

    const socket = new WebSocket('/api/ws')

    socket.onopen = () => {
      setConnected(true)
      socket.send(
        JSON.stringify({
          type: 'info_request',
          kind: 'chatroom_messages',
          timestamp: Date.now()
        })
      )
    }

    socket.onmessage = event => {
      const message = JSON.parse(event.data) as WSMessage
      if (message.for == 'info_request:chatroom_messages') {
        const messages = message.data as Message[]
        setMessages(messages)
      } else if (message.for == 'upload:chatroom_message') {
        const msg = message.data as Message
        setMessages(prev => [...prev.slice(1), msg])
      } else if (message.for == 'delete:chatroom_message') {
        const msg = message.data.fillerMessage as Message
        setMessages(prev => [msg, ...prev.slice(0, -1)])
      } else if (message.for == 'edit:chatroom_message') {
        setMessages(prev =>
          prev.map(msg =>
            msg.id === message.data.id
              ? { ...msg, content: btoa(message.data.newContent) }
              : msg
          )
        )
      }
    }

    socket.onclose = () => {
      setConnected(false)
      setMessages([])
    }

    setWs(socket)

    return () => {
      socket.close()
    }
  }, [])

  useEffect(() => {
    if (messagesDiv.current) {
      messagesDiv.current.scrollTop = messagesDiv.current.scrollHeight
    }
    const all = customIconCache.map(icon => icon.id)
    const allFromMessages = Array.from(
      new Set(
        messages
          .filter(icon => icon.customIcon != null)
          .map(icon => icon.customIcon as string)
      )
    )
    const notInAllIds = allFromMessages
      .filter(id => !all.includes(id))
      .map(id => `"${id}"`)
      .join(',')

    if (notInAllIds.length != 0) {
      ;(async () => {
        const result = await axios.get(
          `/api/berrydash/icon-marketplace/icon?ids=[${notInAllIds}]`
        )
        if (result.data.success) {
          const add: CustomIconEntry[] = []
          for (const item of result.data.data) {
            add.push({
              data: item.data,
              id: item.id
            })
          }
          setCustomIconCache(prev => [
            ...prev,
            ...result.data.data.map((item: CustomIconEntry) => ({
              data: item.data,
              id: item.id
            }))
          ])
        }
      })()
    }
  }, [messages])

  return (
    <div className='box'>
      <BackButton href='/game/berry-dash' />
      <DiscordButton />
      <p className='px-8 mb-4 -mt-2 text-center text-2xl'>
        Berry Dash Chatroom
      </p>
      {connected && (
        <>
          <div
            className='sub-box -m-4 mt-0 flex flex-col gap-2 max-h-[calc(100vh-204px)] overflow-y-auto'
            ref={messagesDiv}
          >
            {messages.map(item => {
              return (
                <div key={item.id} className='sub-box2 flex flex-row gap-1'>
                  <img
                    src={
                      !item.customIcon
                        ? `https://games-r2.lncvrt.xyz/game-assets/berrydash/icons/bird_${
                            item.icon == 1
                              ? GetIconForUser(item.userId)
                              : item.icon
                          }.png`
                        : customIconCache.find(i => i.id === item.customIcon)
                        ? 'data:image/png;base64,' +
                          customIconCache.find(i => i.id === item.customIcon)
                            ?.data
                        : 'https://games-r2.lncvrt.xyz/game-assets/berrydash/other/loading.png'
                    }
                    className='pointer-events-none'
                    width={48}
                    height={48}
                  ></img>
                  <div>
                    <p>{item.username}</p>
                    <p className='w-240 max-w-[calc(100vw-136px)] truncate select-text'>
                      {atob(item.content)}
                    </p>
                  </div>
                </div>
              )
            })}
          </div>
          {loggedIn ? (
            <form
              onSubmit={e => {
                e.preventDefault()
                setInput('')
                ws?.send(
                  JSON.stringify({
                    type: 'upload',
                    kind: 'chatroom_message',
                    data: {
                      content: input,
                      auth: token
                    },
                    timestamp: Date.now()
                  })
                )
              }}
              className='flex flex-row gap-2 -mb-4 mt-6'
            >
              <input
                type='text'
                className='w-full -ml-4 text-center'
                placeholder='Enter a message to send...'
                maxLength={60}
                value={input}
                onChange={e => setInput(e.target.value)}
              ></input>
              <button className='-mr-4'>Send</button>
            </form>
          ) : (
            <p className='text-center -mb-4 mt-6'>
              You must be logged in to send messages
            </p>
          )}
        </>
      )}
      {!connected && (
        <p className='text-center text-red-500'>
          Not connected to the chatroom
        </p>
      )}
    </div>
  )
}
