<script setup lang="ts">
import { ref, onMounted, onUnmounted, computed } from 'vue'
import { register } from 'vue-advanced-chat'
import Badge from 'primevue/badge'
import Button from 'primevue/button'
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 and agent processing state
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,
  typingUsers: isAgentProcessing.value ? [AGENT_ID] : []
}])

// Streaming state
let currentStreamingMessageId: string | null = null
let streamingBuffer = ''
const isAgentProcessing = ref(false)

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

// Handle WebSocket messages
const handleMessage = (data: WebSocketMessage) => {
  console.log('[ChatPanel] Received message:', data)
  if (data.type === 'agent_chunk') {
    console.log('[ChatPanel] Processing agent_chunk, content:', data.content, 'done:', data.done)
    const timestamp = new Date().toTimeString().split(' ')[0].slice(0, 5)

    if (!currentStreamingMessageId) {
      console.log('[ChatPanel] Starting new streaming message')
      // Start new streaming message
      isAgentProcessing.value = true
      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,
        files: []
      }]
    } else {
      // Update existing streaming message
      streamingBuffer += data.content
      const msgIndex = messages.value.findIndex(m => m._id === currentStreamingMessageId)

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

        // Add plot images if present in metadata
        if (data.metadata && data.metadata.plot_urls && Array.isArray(data.metadata.plot_urls)) {
          const plotFiles = data.metadata.plot_urls.map((url: string, idx: number) => ({
            name: `plot_${idx + 1}.png`,
            size: 0,
            type: 'png',
            url: `${BACKEND_URL}${url}`,
            preview: `${BACKEND_URL}${url}`
          }))
          updatedMessage.files = plotFiles
        }

        messages.value[msgIndex] = updatedMessage
        messages.value = [...messages.value]
      }
    }

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

        // Ensure plot images are included in final message
        if (data.metadata && data.metadata.plot_urls && Array.isArray(data.metadata.plot_urls)) {
          const plotFiles = data.metadata.plot_urls.map((url: string, idx: number) => ({
            name: `plot_${idx + 1}.png`,
            size: 0,
            type: 'png',
            url: `${BACKEND_URL}${url}`,
            preview: `${BACKEND_URL}${url}`
          }))
          finalMessage.files = plotFiles
        }

        messages.value[msgIndex] = finalMessage
        messages.value = [...messages.value]
      }

      currentStreamingMessageId = null
      streamingBuffer = ''
      isAgentProcessing.value = false
    }
  }
}

// Stop agent processing
const stopAgent = () => {
  // Send empty message to trigger interrupt without new agent round
  const wsMessage = {
    type: 'agent_user_message',
    session_id: SESSION_ID,
    content: '',
    attachments: []
  }
  wsManager.send(wsMessage)
  isAgentProcessing.value = false
}

// 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 = 'dark'

// Styles to match PrimeVue theme
const chatStyles = computed(() => JSON.stringify({
  general: {
    color: '#cdd6e8',
    colorSpinner: '#00d4aa',
    borderStyle: '1px solid #263452'
  },
  container: {
    background: '#0a0e1a'
  },
  header: {
    background: '#0f1629',
    colorRoomName: '#cdd6e8',
    colorRoomInfo: '#8892a4'
  },
  footer: {
    background: '#0f1629',
    borderStyleInput: '1px solid #263452',
    backgroundInput: '#161e35',
    colorInput: '#cdd6e8',
    colorPlaceholder: '#8892a4',
    colorIcons: '#8892a4'
  },
  content: {
    background: '#0a0e1a'
  },
  message: {
    background: '#161e35',
    backgroundMe: '#1e2d4f',
    color: '#cdd6e8',
    colorMe: '#cdd6e8'
  }
}))

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

  // Focus on the chat input when component mounts
  setTimeout(() => {
    const chatInput = document.querySelector('.vac-textarea') as HTMLTextAreaElement
    if (chatInput) {
      chatInput.focus()
    }
  }, 300)
})

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="100vh"
      :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="false"
      :show-emojis="true"
      :show-reaction-emojis="false"
      :accepted-files="'image/*,video/*,application/pdf'"
      :message-images="true"
      @send-message="sendMessage"
      @fetch-messages="fetchMessages"
      @open-file="openFile"
    />

    <!-- Stop button overlay -->
    <div v-if="isAgentProcessing" class="stop-button-container">
      <Button
        icon="pi pi-stop-circle"
        label="Stop"
        severity="danger"
        @click="stopAgent"
        class="stop-button"
      />
    </div>
  </div>
</template>

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

.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);
}

.stop-button-container {
  position: absolute;
  bottom: 80px;
  right: 20px;
  z-index: 1000;
}

.stop-button {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0%, 100% {
    opacity: 1;
  }
  50% {
    opacity: 0.8;
  }
}
</style>
