<template>
  <div class="container mx-auto px-4 py-8">
    <!-- Loading State -->
    <div v-if="!isMarketReady && ((marketStore.isLoading ?? false) || marketPreloader.isPreloading)" class="flex justify-center items-center min-h-64">
      <div class="flex flex-col items-center space-y-4">
        <div class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
        <p class="text-gray-600">
          {{ marketPreloader.isPreloading ? 'Preloading market...' : 'Loading market...' }}
        </p>
      </div>
    </div>

    <!-- Error State -->
    <div v-else-if="(marketStore.error || marketPreloader.preloadError) && marketStore.products.length === 0" class="flex justify-center items-center min-h-64">
      <div class="text-center">
        <h2 class="text-2xl font-bold text-red-600 mb-4">Failed to load market</h2>
        <p class="text-gray-600 mb-4">{{ marketStore.error || marketPreloader.preloadError }}</p>
        <Button @click="retryLoadMarket" variant="outline">
          Try Again
        </Button>
      </div>
    </div>

    <!-- Market Content -->
    <div v-else>
      <!-- Market Header - Optimized for Mobile -->
      <div class="mb-4 sm:mb-6 lg:mb-8">
        <!-- Market Info and Search - Responsive Layout -->
        <div class="flex flex-col lg:flex-row lg:items-center lg:justify-between gap-3 sm:gap-4 lg:gap-6">
          <!-- Market Info - Compact on Mobile -->
          <div class="flex items-center space-x-3 sm:space-x-4">
            <Avatar v-if="marketStore.activeMarket?.opts?.logo" class="h-10 w-10 sm:h-12 sm:w-12">
              <AvatarImage :src="marketStore.activeMarket.opts.logo" />
              <AvatarFallback>M</AvatarFallback>
            </Avatar>
            <div>
              <h1 class="text-xl sm:text-2xl lg:text-3xl font-bold">
                {{ marketStore.activeMarket?.opts?.name || 'Market' }}
              </h1>
              <p v-if="marketStore.activeMarket?.opts?.description" class="text-muted-foreground text-xs sm:text-sm lg:text-base line-clamp-1 sm:line-clamp-2">
                {{ marketStore.activeMarket.opts.description }}
              </p>
            </div>
          </div>

          <!-- Enhanced Fuzzy Search Bar - Full Width on Mobile -->
          <div class="w-full lg:flex-1 lg:max-w-md">
            <MarketFuzzySearch
              :data="marketStore.products as Product[]"
              :options="searchOptions"
              @results="handleSearchResults"
              @filter-category="handleCategoryFilter"
              class="w-full"
            />
          </div>
        </div>
      </div>



      <!-- Enhanced Category Filters -->
      <CategoryFilterBar
        :categories="allCategories"
        :selected-count="selectedCategoriesCount"
        :filter-mode="filterMode"
        :product-count="productsToDisplay.length"
        @toggle-category="toggleCategory"
        @clear-all="clearAllCategoryFilters"
        @set-filter-mode="setFilterMode"
      />

      <!-- Product Grid with Loading and Empty States -->
      <ProductGrid
        v-if="isMarketReady"
        :products="productsToDisplay as Product[]"
        :is-loading="marketStore.isLoading ?? false"
        loading-message="Loading products..."
        empty-title="No products found"
        empty-message="Try adjusting your search or filters"
        @add-to-cart="addToCart"
        @view-details="viewProduct"
        @view-stall="viewStall"
      />

      <!-- Cart Summary -->
      <div v-if="marketStore.totalCartItems > 0" class="fixed bottom-4 right-4">
        <Button @click="viewCart" class="shadow-lg">
          <ShoppingCart class="w-5 h-5 mr-2" />
          Cart ({{ marketStore.totalCartItems }})
        </Button>
      </div>
    </div>

    <!-- Product Detail Dialog -->
    <ProductDetailDialog
      v-if="selectedProduct"
      :product="selectedProduct"
      :isOpen="showProductDetail"
      @close="closeProductDetail"
      @add-to-cart="handleAddToCart"
    />
  </div>
</template>

<script setup lang="ts">
import { onMounted, onUnmounted, computed, ref } from 'vue'
import { useRouter } from 'vue-router'
import { useMarketStore } from '@/modules/market/stores/market'
import { useMarket } from '../composables/useMarket'
import { useMarketPreloader } from '../composables/useMarketPreloader'
import { useCategoryFilter } from '../composables/useCategoryFilter'
import { config } from '@/lib/config'
import { Button } from '@/components/ui/button'
import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar'
import { ShoppingCart } from 'lucide-vue-next'
import MarketFuzzySearch from '../components/MarketFuzzySearch.vue'
import ProductGrid from '../components/ProductGrid.vue'
import CategoryFilterBar from '../components/CategoryFilterBar.vue'
import ProductDetailDialog from '../components/ProductDetailDialog.vue'
import type { Product } from '../types/market'
import type { FuzzySearchOptions } from '@/composables/useFuzzySearch'

const router = useRouter()
const marketStore = useMarketStore()
const market = useMarket()
const marketPreloader = useMarketPreloader()

// Dynamic category filtering: use search results when available, otherwise all products
const productsForCategoryFilter = computed(() => {
  return searchResults.value.length > 0
    ? searchResults.value
    : (marketStore.products as Product[])
})

// Category filtering with optimized composable
const {
  allCategories,
  selectedCount: selectedCategoriesCount,
  selectedCategoryNames: selectedCategories,
  hasActiveFilters,
  filterMode,
  toggleCategory,
  clearAllCategories: clearAllCategoryFilters,
  setFilterMode
} = useCategoryFilter(productsForCategoryFilter)

let unsubscribe: (() => void) | null = null

// Fuzzy search state
const searchResults = ref<Product[]>([])

// Product detail dialog state
const showProductDetail = ref(false)
const selectedProduct = ref<Product | null>(null)

// Fuzzy search configuration for products and stalls
const searchOptions: FuzzySearchOptions<Product> = {
  fuseOptions: {
    keys: [
      { name: 'name', weight: 0.7 },         // Product name has highest weight
      { name: 'stallName', weight: 0.5 },    // Stall name is important for discovery
      { name: 'description', weight: 0.3 },  // Description provides context
      { name: 'categories', weight: 0.4 }    // Categories help with discovery
    ],
    threshold: 0.4,        // More tolerant of typos (0.0 = perfect match, 1.0 = match anything)
    ignoreLocation: true,  // Don't care about where in the string the match is
    findAllMatches: true,  // Find all matches, not just the first
    minMatchCharLength: 2, // Minimum length of a matched character sequence
    shouldSort: true       // Sort results by score
  },
  resultLimit: 50,         // Limit results for performance
  minSearchLength: 2,      // Start searching after 2 characters
  matchAllWhenSearchEmpty: true
}

// Check if we need to load market data
const needsToLoadMarket = computed(() => {
  return !marketPreloader.isPreloaded.value && 
         !marketPreloader.isPreloading.value && 
         marketStore.products.length === 0
})

// Check if market data is ready (either preloaded or loaded)
const isMarketReady = computed(() => {
  const isLoading = marketStore.isLoading ?? false
  const ready = marketPreloader.isPreloaded.value ||
         (marketStore.products.length > 0 && !isLoading)

  return ready
})

// Products to display (combines search results with category filtering)
const productsToDisplay = computed(() => {
  // Start with either search results or all products
  const baseProducts = searchResults.value.length > 0
    ? searchResults.value
    : marketStore.products

  // Apply category filtering using our composable's proper AND/OR logic
  if (!hasActiveFilters.value) {
    return baseProducts
  }

  // Use the composable's filtering logic which supports AND/OR modes
  return baseProducts.filter(product => {
    if (!product.categories?.length) return false

    // Normalize product categories
    const productCategories = product.categories
      .filter(cat => cat && cat.trim())
      .map(cat => cat.toLowerCase())

    if (productCategories.length === 0) return false

    // Count matches between product categories and selected categories
    const matchingCategories = productCategories.filter(cat =>
      selectedCategories.value.includes(cat)
    )

    // Apply AND/OR logic based on filter mode
    if (filterMode.value === 'all') {
      // AND logic: Product must have ALL selected categories
      return matchingCategories.length === selectedCategories.value.length
    } else {
      // OR logic: Product must have ANY selected category
      return matchingCategories.length > 0
    }
  })
})

const loadMarket = async () => {
  try {
    const naddr = config.market.defaultNaddr
    if (!naddr) {
      throw new Error('No market naddr configured')
    }

    await market.connectToMarket()
    await market.loadMarket(naddr)
    
    // Subscribe to real-time updates
    unsubscribe = market.subscribeToMarketUpdates()
    
  } catch (error) {
    marketStore.setError(error instanceof Error ? error.message : 'Failed to load market')
  }
}

const retryLoadMarket = () => {
  marketStore.setError(null)
  marketPreloader.resetPreload()
  loadMarket()
}

const addToCart = (product: any) => {
  marketStore.addToCart(product)
}

const viewProduct = (product: Product) => {
  selectedProduct.value = product
  showProductDetail.value = true
}

const closeProductDetail = () => {
  showProductDetail.value = false
  selectedProduct.value = null
}

const handleAddToCart = (product: Product, quantity: number) => {
  marketStore.addToCart({ ...product, quantity })
  closeProductDetail()
}

const viewStall = (stallId: string) => {
  // Navigate to the stall view page
  router.push(`/market/stall/${stallId}`)
}

const viewCart = () => {
  router.push('/cart')
}

// Handle fuzzy search results
const handleSearchResults = (results: Product[]) => {
  searchResults.value = results
}

// Handle category filtering from fuzzy search
const handleCategoryFilter = (category: string) => {
  toggleCategory(category)
}

onMounted(() => {
  // Only load market if it hasn't been preloaded
  if (needsToLoadMarket.value) {
    loadMarket()
  } else if (marketPreloader.isPreloaded.value) {
    // Subscribe to real-time updates if market was preloaded
    unsubscribe = market.subscribeToMarketUpdates()
  }
})

onUnmounted(() => {
  if (unsubscribe) {
    unsubscribe()
  }
  market.disconnectFromMarket()
})
</script> 
