/**
 * ProductSearchPicker — reusable component for searching and selecting WooCommerce products.
 * Uses debounced search against the WP REST API.
 *
 * @package BoostBot
 * @since 1.3.0
 */

import { useState, useCallback, useRef, useEffect } from 'react'
import { Search, X, Loader2 } from 'lucide-react'
import { t } from '@/lib/i18n'
import { apiClient } from '@/api/client'

interface ProductResult {
  id: number
  name: string
  price: string
  formatted_price?: string
  image?: string
}

interface ProductSearchPickerProps {
  selectedIds: number[]
  onChange: (ids: number[]) => void
  label?: string
  placeholder?: string
  language?: string
  maxSelections?: number
}

export function ProductSearchPicker({
  selectedIds,
  onChange,
  label,
  placeholder,
  language,
  maxSelections,
}: ProductSearchPickerProps) {
  const [query, setQuery] = useState('')
  const [results, setResults] = useState<ProductResult[]>([])
  const [isSearching, setIsSearching] = useState(false)
  const [selectedProducts, setSelectedProducts] = useState<Map<number, ProductResult>>(new Map())
  const [showResults, setShowResults] = useState(false)
  const searchTimeoutRef = useRef<ReturnType<typeof setTimeout>>()
  const containerRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    if (selectedIds.length > 0 && selectedProducts.size === 0) {
      const loadSelectedProducts = async () => {
        const products = new Map<number, ProductResult>()
        for (const id of selectedIds) {
          try {
            const resp = await apiClient.get<{ data: { product: ProductResult } }>(`woocommerce/products/${id}`)
            if (resp?.data?.product) {
              products.set(id, resp.data.product)
            }
          } catch {
            products.set(id, { id, name: `#${id}`, price: '' })
          }
        }
        setSelectedProducts(products)
      }
      loadSelectedProducts()
    }
  }, []) // Only on mount

  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
        setShowResults(false)
      }
    }
    document.addEventListener('mousedown', handleClickOutside)
    return () => document.removeEventListener('mousedown', handleClickOutside)
  }, [])

  const searchProducts = useCallback(async (searchQuery: string) => {
    if (!searchQuery.trim()) {
      setResults([])
      setIsSearching(false)
      return
    }

    setIsSearching(true)
    try {
      const params: Record<string, unknown> = { q: searchQuery, limit: 10 }
      if (language) params.language = language
      const resp = await apiClient.get<{ data: { products: ProductResult[] } }>(
        'woocommerce/products/search',
        params,
      )
      setResults(resp?.data?.products || [])
    } catch {
      setResults([])
    } finally {
      setIsSearching(false)
    }
  }, [language])

  const handleQueryChange = useCallback((value: string) => {
    setQuery(value)
    setShowResults(true)

    if (searchTimeoutRef.current) {
      clearTimeout(searchTimeoutRef.current)
    }

    searchTimeoutRef.current = setTimeout(() => {
      searchProducts(value)
    }, 300)
  }, [searchProducts])

  const handleSelect = useCallback((product: ProductResult) => {
    if (selectedIds.includes(product.id)) return
    if (maxSelections && selectedIds.length >= maxSelections) return

    const newIds = [...selectedIds, product.id]
    setSelectedProducts(prev => {
      const next = new Map(prev)
      next.set(product.id, product)
      return next
    })
    onChange(newIds)
    setQuery('')
    setResults([])
    setShowResults(false)
  }, [selectedIds, onChange, maxSelections])

  const handleRemove = useCallback((id: number) => {
    const newIds = selectedIds.filter(pid => pid !== id)
    setSelectedProducts(prev => {
      const next = new Map(prev)
      next.delete(id)
      return next
    })
    onChange(newIds)
  }, [selectedIds, onChange])

  const filteredResults = results.filter(p => !selectedIds.includes(p.id))

  return (
    <div ref={containerRef}>
      {label && (
        <label className="block text-sm font-medium text-gray-700 mb-2">{label}</label>
      )}

      {/* Search input */}
      <div className="relative">
        <Search className="absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400 pointer-events-none" />
        {isSearching && (
          <Loader2 className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400 animate-spin" />
        )}
        <input
          type="text"
          value={query}
          onChange={e => handleQueryChange(e.target.value)}
          onFocus={() => { if (query.trim()) setShowResults(true) }}
          placeholder={placeholder || t('Search products...')}
          className="w-full pr-10 pl-10 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500 text-sm"
        />
      </div>

      {/* Search results dropdown */}
      {showResults && query.trim() && (
        <div className="mt-1 border border-gray-200 rounded-lg bg-white shadow-lg max-h-60 overflow-y-auto z-50 relative">
          {isSearching ? (
            <div className="px-4 py-3 text-sm text-gray-500 text-center flex items-center justify-center gap-2">
              <Loader2 className="w-4 h-4 animate-spin" />
              {t('Searching...')}
            </div>
          ) : filteredResults.length === 0 ? (
            <div className="px-4 py-3 text-sm text-gray-500 text-center">
              {t('No products found')}
            </div>
          ) : (
            filteredResults.map(product => (
              <button
                key={product.id}
                type="button"
                onClick={() => handleSelect(product)}
                className="w-full flex items-center gap-3 px-3 py-2.5 hover:bg-gray-50 transition-colors text-sm border-b border-gray-100 last:border-0 cursor-pointer"
              >
                {product.image && (
                  <img
                    src={product.image}
                    alt=""
                    className="w-10 h-10 object-cover rounded border border-gray-200 flex-shrink-0"
                  />
                )}
                <div className="flex-1 text-right min-w-0">
                  <p className="font-medium text-gray-900 truncate">{product.name}</p>
                  {product.formatted_price && (
                    <p className="text-xs text-gray-500">{product.formatted_price}</p>
                  )}
                </div>
              </button>
            ))
          )}
        </div>
      )}

      {/* Selected products tags */}
      {selectedIds.length > 0 && (
        <div className="mt-3">
          <p className="text-xs font-medium text-gray-500 mb-1.5">
            {t('Selected products')} ({selectedIds.length})
          </p>
          <div className="flex flex-wrap gap-2">
            {selectedIds.map(id => {
              const product = selectedProducts.get(id)
              const displayName = product?.name || `#${id}`
              return (
                <span
                  key={id}
                  className="inline-flex items-center gap-1.5 px-3 py-1.5 bg-purple-50 text-purple-800 rounded-full text-sm border border-purple-200"
                >
                  {displayName}
                  <button
                    type="button"
                    onClick={() => handleRemove(id)}
                    className="p-0.5 hover:bg-purple-200 rounded-full transition-colors cursor-pointer"
                    title={t('Remove')}
                  >
                    <X className="w-3 h-3" />
                  </button>
                </span>
              )
            })}
          </div>
        </div>
      )}
    </div>
  )
}
