<template>
  <div class="flex flex-col h-full">
    <!-- Mobile: Peer List View -->
    <div v-if="isMobile && (!selectedPeer || !showChat)" class="flex flex-col h-full">
      <!-- Header -->
      <div class="flex items-center justify-between p-4 border-b">
        <div class="flex items-center space-x-3">
          <h2 class="text-lg font-semibold">Chat</h2>
          <Badge v-if="isConnected" variant="default" class="text-xs">
            Connected
          </Badge>
          <Badge v-else variant="secondary" class="text-xs">
            Disconnected
          </Badge>
          <!-- Total unread count -->
          <Badge v-if="totalUnreadCount > 0" class="bg-blue-500 text-white text-xs">
            {{ totalUnreadCount }} unread
          </Badge>
        </div>
        <Button @click="refreshPeers" :disabled="isLoading" size="sm">
          <RefreshCw v-if="isLoading" class="h-4 w-4 animate-spin" />
          <RefreshCw v-else class="h-4 w-4" />
          <span class="hidden sm:inline ml-2">Refresh</span>
        </Button>
      </div>

      <!-- Peer List -->
      <div class="flex-1 flex flex-col overflow-hidden">
        <div class="p-4 border-b flex-shrink-0">
          <div class="flex items-center justify-between mb-2">
            <h3 class="font-medium">Peers ({{ filteredPeers.length }})</h3>
            <span v-if="isSearching" class="text-xs text-muted-foreground">
              {{ resultCount }} found
            </span>
          </div>
          <!-- Search Input -->
          <div class="relative">
            <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
              <Search class="h-4 w-4 text-muted-foreground" />
            </div>
            <Input
              v-model="searchQuery"
              placeholder="Search peers by name or pubkey..."
              class="pl-10 pr-10"
            />
            <div v-if="searchQuery" class="absolute inset-y-0 right-0 pr-3 flex items-center">
              <Button
                variant="ghost"
                size="sm"
                @click="clearSearch"
                class="h-6 w-6 p-0 hover:bg-muted"
              >
                <X class="h-3 w-3" />
                <span class="sr-only">Clear search</span>
              </Button>
            </div>
          </div>
        </div>
        <ScrollArea class="flex-1">
          <div class="p-2 space-y-1">
            <!-- No results message -->
            <div v-if="isSearching && filteredPeers.length === 0" class="text-center py-8 text-muted-foreground">
              <Search class="h-8 w-8 mx-auto mb-2 opacity-50" />
              <p class="text-sm">No peers found matching "{{ searchQuery }}"</p>
              <p class="text-xs mt-1">Try searching by username or pubkey</p>
            </div>
            
            <!-- Peer list -->
            <div
              v-for="peer in filteredPeers"
              :key="peer.user_id"
              @click="selectPeer(peer)"
              :class="[
                'flex items-center space-x-3 p-3 rounded-lg cursor-pointer transition-colors touch-manipulation relative',
                selectedPeer?.user_id === peer.user_id
                  ? 'bg-primary text-primary-foreground'
                  : 'hover:bg-muted active:bg-muted/80'
              ]"
            >
              <Avatar class="h-10 w-10 sm:h-8 sm:w-8">
                <AvatarImage v-if="getPeerAvatar(peer)" :src="getPeerAvatar(peer)!" />
                <AvatarFallback>{{ getPeerInitials(peer) }}</AvatarFallback>
              </Avatar>
              <div class="flex-1 min-w-0">
                <p class="text-sm font-medium truncate">
                  {{ peer.username || 'Unknown User' }}
                </p>
                <p class="text-xs text-muted-foreground truncate">
                  {{ formatPubkey(peer.pubkey) }}
                </p>
              </div>
              <!-- Unread message indicator -->
              <div v-if="getUnreadCount(peer.pubkey) > 0" class="flex-shrink-0">
                <Badge class="bg-blue-500 text-white h-6 w-6 rounded-full p-0 flex items-center justify-center text-xs font-bold">
                  {{ getUnreadCount(peer.pubkey) > 99 ? '99+' : getUnreadCount(peer.pubkey) }}
                </Badge>
              </div>
            </div>
          </div>
        </ScrollArea>
      </div>
    </div>

    <!-- Mobile: Chat View -->
    <div v-else-if="isMobile && showChat" class="flex flex-col h-full">
      <!-- Chat Header with Back Button -->
      <div class="flex items-center justify-between p-4 border-b">
        <div class="flex items-center space-x-3">
          <Button 
            variant="ghost" 
            size="icon" 
            @click="goBackToPeers"
            class="mr-2"
          >
            <ArrowLeft class="h-5 w-5" />
          </Button>
          <Avatar class="h-8 w-8">
            <AvatarImage v-if="selectedPeer && getPeerAvatar(selectedPeer)" :src="getPeerAvatar(selectedPeer)!" />
            <AvatarFallback>{{ selectedPeer ? getPeerInitials(selectedPeer) : 'U' }}</AvatarFallback>
          </Avatar>
          <div>
            <h3 class="font-medium">{{ selectedPeer?.username || 'Unknown User' }}</h3>
            <p class="text-xs text-muted-foreground">
              {{ selectedPeer ? formatPubkey(selectedPeer.pubkey) : '' }}
            </p>
          </div>
        </div>
        <div class="flex items-center space-x-2">
          <Badge v-if="isConnected" variant="default" class="text-xs">
            Connected
          </Badge>
          <Badge v-else variant="secondary" class="text-xs">
            Disconnected
          </Badge>
          <!-- Unread count for current peer -->
          <Badge v-if="selectedPeer && getUnreadCount(selectedPeer.pubkey) > 0" class="bg-blue-500 text-white text-xs">
            {{ getUnreadCount(selectedPeer.pubkey) }} unread
          </Badge>
        </div>
      </div>

      <!-- Messages -->
      <ScrollArea class="flex-1 p-4" ref="messagesScrollArea">
        <div class="space-y-4">
          <div
            v-for="message in currentMessages"
            :key="message.id"
            :class="[
              'flex',
              message.sent ? 'justify-end' : 'justify-start'
            ]"
          >
            <div
              :class="[
                'max-w-xs lg:max-w-md px-4 py-2 rounded-lg',
                message.sent
                  ? 'bg-primary text-primary-foreground'
                  : 'bg-muted'
              ]"
            >
              <p class="text-sm">{{ message.content }}</p>
              <p class="text-xs opacity-70 mt-1">
                {{ formatTime(message.created_at) }}
              </p>
            </div>
          </div>
        </div>
        <!-- Hidden element at bottom for scrolling -->
        <div ref="scrollTarget" class="h-1" />
      </ScrollArea>

      <!-- Message Input -->
      <div class="p-4 border-t">
        <form @submit.prevent="sendMessage" class="flex space-x-2">
          <Input
            v-model="messageInput"
            placeholder="Type a message..."
            :disabled="!isConnected || !selectedPeer"
            class="flex-1"
          />
          <Button type="submit" :disabled="!isConnected || !selectedPeer || !messageInput.trim()">
            <Send class="h-4 w-4" />
          </Button>
        </form>
      </div>
    </div>

    <!-- Desktop: Full Layout -->
    <div v-else-if="!isMobile" class="flex flex-col h-full">
      <!-- Header -->
      <div class="flex items-center justify-between p-4 border-b">
        <div class="flex items-center space-x-3">
          <h2 class="text-lg font-semibold">Chat</h2>
          <Badge v-if="isConnected" variant="default" class="text-xs">
            Connected
          </Badge>
          <Badge v-else variant="secondary" class="text-xs">
            Disconnected
          </Badge>
          <!-- Total unread count -->
          <Badge v-if="totalUnreadCount > 0" class="bg-blue-500 text-white text-xs">
            {{ totalUnreadCount }} unread
          </Badge>
        </div>
        <Button @click="refreshPeers" :disabled="isLoading" size="sm">
          <RefreshCw v-if="isLoading" class="h-4 w-4 animate-spin" />
          <RefreshCw v-else class="h-4 w-4" />
          Refresh Peers
        </Button>
      </div>

      <!-- Main Content -->
      <div class="flex flex-1 overflow-hidden">
        <!-- Peer List -->
        <div class="w-80 border-r bg-muted/30 flex flex-col">
          <div class="p-4 border-b flex-shrink-0">
            <div class="flex items-center justify-between mb-2">
              <h3 class="font-medium">Peers ({{ filteredPeers.length }})</h3>
              <span v-if="isSearching" class="text-xs text-muted-foreground">
                {{ resultCount }} found
              </span>
            </div>
            <!-- Search Input -->
            <div class="relative">
              <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                <Search class="h-4 w-4 text-muted-foreground" />
              </div>
              <Input
                v-model="searchQuery"
                placeholder="Search peers by name or pubkey..."
                class="pl-10 pr-10"
              />
              <div v-if="searchQuery" class="absolute inset-y-0 right-0 pr-3 flex items-center">
                <Button
                  variant="ghost"
                  size="sm"
                  @click="clearSearch"
                  class="h-6 w-6 p-0 hover:bg-muted"
                >
                  <X class="h-3 w-3" />
                  <span class="sr-only">Clear search</span>
                </Button>
              </div>
            </div>
          </div>
          <ScrollArea class="flex-1">
            <div class="p-2 space-y-1">
              <!-- No results message -->
              <div v-if="isSearching && filteredPeers.length === 0" class="text-center py-8 text-muted-foreground">
                <Search class="h-8 w-8 mx-auto mb-2 opacity-50" />
                <p class="text-sm">No peers found matching "{{ searchQuery }}"</p>
                <p class="text-xs mt-1">Try searching by username or pubkey</p>
              </div>
              
              <!-- Peer list -->
              <div
                v-for="peer in filteredPeers"
                :key="peer.user_id"
                @click="selectPeer(peer)"
                :class="[
                  'flex items-center space-x-3 p-3 rounded-lg cursor-pointer transition-colors relative',
                  selectedPeer?.user_id === peer.user_id
                    ? 'bg-primary text-primary-foreground'
                    : 'hover:bg-muted'
                ]"
              >
                <Avatar class="h-8 w-8">
                  <AvatarImage v-if="getPeerAvatar(peer)" :src="getPeerAvatar(peer)!" />
                  <AvatarFallback>{{ getPeerInitials(peer) }}</AvatarFallback>
                </Avatar>
                <div class="flex-1 min-w-0">
                  <p class="text-sm font-medium truncate">
                    {{ peer.username || 'Unknown User' }}
                  </p>
                  <p class="text-xs text-muted-foreground truncate">
                    {{ formatPubkey(peer.pubkey) }}
                  </p>
                </div>
                <!-- Unread message indicator -->
                <div v-if="getUnreadCount(peer.pubkey) > 0" class="flex-shrink-0">
                  <Badge class="bg-blue-500 text-white h-6 w-6 rounded-full p-0 flex items-center justify-center text-xs font-bold">
                    {{ getUnreadCount(peer.pubkey) > 99 ? '99+' : getUnreadCount(peer.pubkey) }}
                  </Badge>
                </div>
              </div>
            </div>
          </ScrollArea>
        </div>

        <!-- Chat Area -->
        <div class="flex-1 flex flex-col">
          <!-- Chat Header - Always present to maintain layout -->
          <div class="p-4 border-b" :class="{ 'h-16': !selectedPeer }">
            <div v-if="selectedPeer" class="flex items-center space-x-3">
              <Avatar class="h-8 w-8">
                <AvatarImage v-if="getPeerAvatar(selectedPeer)" :src="getPeerAvatar(selectedPeer)!" />
                <AvatarFallback>{{ getPeerInitials(selectedPeer) }}</AvatarFallback>
              </Avatar>
              <div>
                <h3 class="font-medium">{{ selectedPeer.username || 'Unknown User' }}</h3>
                <p class="text-sm text-muted-foreground">
                  {{ formatPubkey(selectedPeer.pubkey) }}
                </p>
              </div>
            </div>
            <div v-else class="h-8"></div>
          </div>

          <!-- Messages -->
          <ScrollArea v-if="selectedPeer" class="flex-1 p-4" ref="messagesScrollArea">
            <div class="space-y-4" ref="messagesContainer">
              <div
                v-for="message in currentMessages"
                :key="message.id"
                :class="[
                  'flex',
                  message.sent ? 'justify-end' : 'justify-start'
                ]"
              >
                <div
                  :class="[
                    'max-w-xs lg:max-w-md px-4 py-2 rounded-lg',
                    message.sent
                      ? 'bg-primary text-primary-foreground'
                      : 'bg-muted'
                  ]"
                >
                  <p class="text-sm">{{ message.content }}</p>
                  <p class="text-xs opacity-70 mt-1">
                    {{ formatTime(message.created_at) }}
                  </p>
                </div>
              </div>
            </div>
            <!-- Hidden element at bottom for scrolling -->
            <div ref="scrollTarget" class="h-1" />
          </ScrollArea>

          <!-- Message Input -->
          <div v-if="selectedPeer" class="p-4 border-t">
            <form @submit.prevent="sendMessage" class="flex space-x-2">
              <Input
                v-model="messageInput"
                placeholder="Type a message..."
                :disabled="!isConnected || !selectedPeer"
                class="flex-1"
              />
              <Button type="submit" :disabled="!isConnected || !selectedPeer || !messageInput.trim()">
                <Send class="h-4 w-4" />
              </Button>
            </form>
          </div>

          <!-- No Peer Selected -->
          <div v-else class="flex-1 flex items-center justify-center">
            <div class="text-center">
              <MessageSquare class="h-12 w-12 text-muted-foreground mx-auto mb-4" />
              <h3 class="text-lg font-medium mb-2">No peer selected</h3>
              <p class="text-muted-foreground">
                Select a peer from the list to start chatting
              </p>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, nextTick, watch } from 'vue'
import { Send, RefreshCw, MessageSquare, ArrowLeft, Search, X } from 'lucide-vue-next'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Badge } from '@/components/ui/badge'
import { ScrollArea } from '@/components/ui/scroll-area'
import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar'
import { nostrChat } from '@/composables/useNostrChat'

import { useFuzzySearch } from '@/composables/useFuzzySearch'

// Types
interface Peer {
  user_id: string
  username: string
  pubkey: string
}

// State
const peers = computed(() => nostrChat.peers.value)
const selectedPeer = ref<Peer | null>(null)
const messageInput = ref('')

const isLoading = ref(false)
const showChat = ref(false)
const messagesScrollArea = ref<HTMLElement | null>(null)
const messagesContainer = ref<HTMLElement | null>(null)
const scrollTarget = ref<HTMLElement | null>(null)

// Mobile detection
const isMobile = ref(false)

// Nostr chat composable (singleton)
const {
  isConnected,
  messages,
  connect,
  disconnect,
  subscribeToPeer,
  sendMessage: sendNostrMessage,
  onMessageAdded,
  markMessagesAsRead,
  getUnreadCount,
  totalUnreadCount,
  getLatestMessageTimestamp
} = nostrChat

// Computed
const currentMessages = computed(() => {
  if (!selectedPeer.value) return []
  const peerMessages = messages.value.get(selectedPeer.value.pubkey) || []
  
  // Sort messages by timestamp (oldest first) to ensure chronological order
  const sortedMessages = [...peerMessages].sort((a, b) => a.created_at - b.created_at)
  
  return sortedMessages
})

// Sort peers by latest message timestamp (newest first) and unread status
const sortedPeers = computed(() => {
  const sorted = [...peers.value].sort((a, b) => {
    const aTimestamp = getLatestMessageTimestamp(a.pubkey)
    const bTimestamp = getLatestMessageTimestamp(b.pubkey)
    const aUnreadCount = getUnreadCount(a.pubkey)
    const bUnreadCount = getUnreadCount(b.pubkey)
    
    // First, sort by unread count (peers with unread messages appear first)
    if (aUnreadCount > 0 && bUnreadCount === 0) return -1
    if (aUnreadCount === 0 && bUnreadCount > 0) return 1
    
    // Then, sort by latest message timestamp (newest first)
    if (aTimestamp !== bTimestamp) {
      return bTimestamp - aTimestamp
    }
    
    // Finally, sort alphabetically by username for peers with same timestamp
    return (a.username || '').localeCompare(b.username || '')
  })
  
  return sorted
})

// Fuzzy search for peers
// This integrates the useFuzzySearch composable to provide intelligent search functionality
// for finding peers by username or pubkey with typo tolerance and scoring
const {
  searchQuery,
  filteredItems: filteredPeers,
  isSearching,
  resultCount,
  clearSearch
} = useFuzzySearch(sortedPeers, {
  fuseOptions: {
    keys: [
      { name: 'username', weight: 0.7 },  // Username has higher weight for better UX
      { name: 'pubkey', weight: 0.3 }     // Pubkey has lower weight but still searchable
    ],
    threshold: 0.3,                       // Fuzzy matching threshold (0.0 = perfect, 1.0 = match anything)
    distance: 100,                        // Maximum distance for fuzzy matching
    ignoreLocation: true,                 // Ignore location for better performance
    useExtendedSearch: false,             // Don't use extended search syntax
    minMatchCharLength: 1,                // Minimum characters to match
    shouldSort: true,                     // Sort results by relevance
    findAllMatches: false,                // Don't find all matches for performance
    location: 0,                          // Start search from beginning
    isCaseSensitive: false,               // Case insensitive search
  },
  resultLimit: 50,                        // Limit results for performance
  matchAllWhenSearchEmpty: true,          // Show all peers when search is empty
  minSearchLength: 1,                     // Start searching after 1 character
})

// Check if device is mobile
const checkMobile = () => {
  isMobile.value = window.innerWidth < 768 // md breakpoint
}

// Mobile navigation
const goBackToPeers = () => {
  showChat.value = false
  selectedPeer.value = null
}

// Methods



const refreshPeers = async () => {
  isLoading.value = true
  try {
    await nostrChat.loadPeers()
  } catch (error) {
    console.error('Failed to refresh peers:', error)
  } finally {
    isLoading.value = false
  }
}

const selectPeer = async (peer: Peer) => {
  selectedPeer.value = peer
  messageInput.value = ''
  
  // Mark messages as read for this peer
  markMessagesAsRead(peer.pubkey)
  
  // On mobile, show chat view
  if (isMobile.value) {
    showChat.value = true
  }
  
  // Subscribe to messages from this peer
  await subscribeToPeer(peer.pubkey)
  
  // Scroll to bottom to show latest messages when selecting a peer
  nextTick(() => {
    scrollToBottom()
  })
}

const sendMessage = async () => {
  if (!selectedPeer.value || !messageInput.value.trim()) return
  
  try {
    await sendNostrMessage(selectedPeer.value.pubkey, messageInput.value)
    messageInput.value = ''
    
    // Scroll to bottom
    nextTick(() => {
      scrollToBottom()
    })
  } catch (error) {
    console.error('Failed to send message:', error)
  }
}

const scrollToBottom = () => {
  nextTick(() => {
    if (scrollTarget.value) {
      // Use scrollIntoView on the target element
      scrollTarget.value.scrollIntoView({ 
        behavior: 'smooth',
        block: 'end'
      })
    }
  })
}

const formatPubkey = (pubkey: string) => {
  return pubkey.slice(0, 8) + '...' + pubkey.slice(-8)
}

const formatTime = (timestamp: number) => {
  return new Date(timestamp * 1000).toLocaleTimeString([], {
    hour: '2-digit',
    minute: '2-digit'
  })
}

const getPeerAvatar = (_peer: Peer) => {
  // You can implement avatar logic here
  return null
}

const getPeerInitials = (peer: Peer) => {
  if (peer.username) {
    return peer.username.slice(0, 2).toUpperCase()
  }
  return peer.pubkey.slice(0, 2).toUpperCase()
}



// Lifecycle
onMounted(async () => {
  checkMobile()
  window.addEventListener('resize', checkMobile)
  
  // Set up message callback
  onMessageAdded.value = (peerPubkey: string) => {
    if (selectedPeer.value && selectedPeer.value.pubkey === peerPubkey) {
      nextTick(() => {
        scrollToBottom()
      })
    }
  }
  
  // If not connected, connect
  if (!isConnected.value) {
    await connect()
  }
  
  // If no peers loaded, load them
  if (peers.value.length === 0) {
    await nostrChat.loadPeers()
  }
})

onUnmounted(() => {
  window.removeEventListener('resize', checkMobile)
  disconnect()
})

// Watch for connection state changes
watch(isConnected, async (connected, prevConnected) => {
  // Note: Peer subscriptions are handled by the preloader
})

// Watch for new messages and scroll to bottom
watch(currentMessages, (newMessages, oldMessages) => {
  // Scroll to bottom when new messages are added
  if (newMessages.length > 0 && (!oldMessages || newMessages.length > oldMessages.length)) {
    nextTick(() => {
      scrollToBottom()
    })
  }
})
</script> 