<script setup lang="ts">
import { ref, onMounted, onUnmounted, computed } from 'vue'
import { register } from 'vue-advanced-chat'
import Badge from 'primevue/badge'
import { wsManager } from '../composables/useWebSocket'
import type { WebSocketMessage } from '../composables/useWebSocket'

register()

const SESSION_ID = 'default'
const CURRENT_USER_ID = 'user-123'
const AGENT_ID = 'agent'
const BACKEND_URL = 'http://localhost:8080'

// Chat state
const messages = ref<any[]>([])
const messagesLoaded = ref(false)
const isConnected = wsManager.isConnected

// Reactive rooms that update based on WebSocket connection
const rooms = computed(() => [{
  roomId: SESSION_ID,
  roomName: 'AI Agent',
  avatar: null,
  users: [
    { _id: CURRENT_USER_ID, username: 'You' },
    { _id: AGENT_ID, username: 'AI Agent', status: { state: isConnected.value ? 'online' : 'offline' } }
  ],
  unreadCount: 0
}])

// Streaming state
let currentStreamingMessageId: string | null = null
let streamingBuffer = ''

// Generate message ID
const generateMessageId = () => `msg-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`

// Handle WebSocket messages
const handleMessage = (data: WebSocketMessage) => {
  if (data.type === 'agent_chunk') {
    const timestamp = new Date().toTimeString().split(' ')[0].slice(0, 5)

    if (!currentStreamingMessageId) {
      // Start new streaming message
      currentStreamingMessageId = generateMessageId()
      streamingBuffer = data.content

      messages.value = [...messages.value, {
        _id: currentStreamingMessageId,
        content: streamingBuffer,
        senderId: AGENT_ID,
        timestamp: timestamp,
        date: new Date().toLocaleDateString(),
        saved: false,
        distributed: false,
        seen: false
      }]
    } else {
      // Update existing streaming message
      streamingBuffer += data.content
      const msgIndex = messages.value.findIndex(m => m._id === currentStreamingMessageId)

      if (msgIndex !== -1) {
        messages.value[msgIndex] = {
          ...messages.value[msgIndex],
          content: streamingBuffer
        }
        messages.value = [...messages.value]
      }
    }

    if (data.done) {
      // Mark message as complete
      const msgIndex = messages.value.findIndex(m => m._id === currentStreamingMessageId)
      if (msgIndex !== -1) {
        messages.value[msgIndex] = {
          ...messages.value[msgIndex],
          saved: true,
          distributed: true,
          seen: true
        }
        messages.value = [...messages.value]
      }

      currentStreamingMessageId = null
      streamingBuffer = ''
    }
  }
}

// Send message handler
const sendMessage = async (event: any) => {
  // Extract data from CustomEvent.detail[0]
  const data = event.detail?.[0] || event

  const content = data.content || ''
  const files = data.files
  const roomId = data.roomId

  const timestamp = new Date().toTimeString().split(' ')[0].slice(0, 5)
  const messageId = generateMessageId()

  // Process files
  let attachments: string[] = []
  let messageFiles: any[] = []

  if (files && files.length > 0) {
    // Upload files to backend
    for (const file of files) {
      try {
        const formData = new FormData()
        // Convert blob URL to actual file if needed
        const response = await fetch(file.url)
        const blob = await response.blob()
        const actualFile = new File([blob], file.name, { type: file.type })
        formData.append('file', actualFile)

        const uploadResponse = await fetch(`${BACKEND_URL}/api/upload`, {
          method: 'POST',
          body: formData
        })

        if (!uploadResponse.ok) {
          throw new Error('Upload failed')
        }

        const uploadData = await uploadResponse.json()
        const fileUrl = `${BACKEND_URL}${uploadData.url}`
        attachments.push(fileUrl)

        messageFiles.push({
          name: file.name,
          size: uploadData.size,
          type: file.extension || file.type,
          url: fileUrl,
          preview: file.url // Keep the blob URL for preview
        })
      } catch (error) {
        console.error('File upload error:', error)
      }
    }
  }

  // Add user message to UI
  const userMessage = {
    _id: messageId,
    content: content,
    senderId: CURRENT_USER_ID,
    timestamp: timestamp,
    date: new Date().toLocaleDateString(),
    saved: true,
    distributed: false,
    seen: false,
    files: messageFiles
  }

  messages.value = [...messages.value, userMessage]

  // Send to backend via WebSocket
  const wsMessage = {
    type: 'agent_user_message',
    session_id: roomId || SESSION_ID,
    content: content,
    attachments: attachments
  }
  wsManager.send(wsMessage)

  // Mark as distributed
  setTimeout(() => {
    const msgIndex = messages.value.findIndex(m => m._id === messageId)
    if (msgIndex !== -1) {
      messages.value[msgIndex] = {
        ...messages.value[msgIndex],
        distributed: true,
        seen: true
      }
      messages.value = [...messages.value]
    }
  }, 100)
}

// Fetch messages handler (for pagination, not needed for simple chat)
const fetchMessages = ({ room, options }: any) => {
  messagesLoaded.value = true
}

// Open file handler
const openFile = ({ file }: any) => {
  window.open(file.url, '_blank')
}

// Theme configuration for dark mode
const chatTheme = 'light'

// Styles to match PrimeVue theme
const chatStyles = computed(() => JSON.stringify({
  general: {
    color: 'var(--p-surface-900)',
    colorSpinner: 'var(--p-primary-color)',
    borderStyle: '1px solid var(--p-surface-200)'
  },
  container: {
    background: 'var(--p-surface-0)'
  },
  header: {
    background: 'var(--p-surface-50)',
    colorRoomName: 'var(--p-surface-900)',
    colorRoomInfo: 'var(--p-surface-700)'
  },
  footer: {
    background: 'var(--p-surface-50)',
    borderStyleInput: '1px solid var(--p-surface-300)',
    backgroundInput: 'var(--p-surface-200)',
    colorInput: 'var(--p-surface-900)',
    colorPlaceholder: 'var(--p-surface-400)',
    colorIcons: 'var(--p-surface-400)'
  },
  content: {
    background: 'var(--p-surface-0)'
  },
  message: {
    background: 'var(--p-surface-100)',
    backgroundMe: 'var(--p-primary-color)',
    color: 'var(--p-surface-900)',
    colorMe: 'var(--p-primary-contrast-color)'
  }
}))

onMounted(() => {
  wsManager.addHandler(handleMessage)
  // Mark messages as loaded after initialization
  messagesLoaded.value = true
})

onUnmounted(() => {
  wsManager.removeHandler(handleMessage)
})
</script>

<template>
  <div class="chat-container">
<!--
    <div class="chat-header-custom">
      <span class="chat-title">AI Agent Chat</span>
      <Badge
        :value="isConnected ? 'Connected' : 'Disconnected'"
        :severity="isConnected ? 'success' : 'danger'"
      />
    </div>
-->

    <vue-advanced-chat
      height="calc(100vh - 60px)"
      :current-user-id="CURRENT_USER_ID"
      :rooms="JSON.stringify(rooms)"
      :messages="JSON.stringify(messages)"
      :messages-loaded="messagesLoaded"
      :room-id="SESSION_ID"
      :theme="chatTheme"
      :styles="chatStyles"
      :single-room="true"
      :rooms-list-opened="false"
      :show-add-room="false"
      :show-audio="false"
      :show-files="true"
      :show-emojis="true"
      :show-reaction-emojis="false"
      :accepted-files="'image/*,video/*,application/pdf'"
      @send-message="sendMessage"
      @fetch-messages="fetchMessages"
      @open-file="openFile"
    />
  </div>
</template>

<style scoped>
.chat-container {
  height: 100% !important;
  display: flex;
  flex-direction: column;
  background: var(--p-surface-0);
  overflow: hidden;
}

.chat-container :deep(.vac-container) {
  height: 100% !important;
}

.chat-container :deep(.vac-text-message) {
  white-space: pre-wrap;
}

.chat-header-custom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 1.5rem;
  background: var(--p-surface-50);
  border-bottom: 1px solid var(--p-surface-200);
  flex-shrink: 0;
}

.chat-title {
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--p-surface-900);
}
</style>
