/**
 * IndexedProductSearchPicker — product search picker that only shows indexed (knowledge base) products.
 * Queries GET /woocommerce/indexed-products instead of raw WooCommerce search.
 *
 * @package BoostBot
 * @since 1.3.0
 */

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

interface IndexedProduct {
  id: number
  name: string
  price: string
  formatted_price?: string
  image?: string
  categories?: { id: number; name: string }[]
  indexed: boolean
}

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

export function IndexedProductSearchPicker({
  selectedIds,
  onChange,
  label,
  placeholder,
  language,
  maxSelections,
}: IndexedProductSearchPickerProps) {
  const [query, setQuery] = useState('')
  const [results, setResults] = useState<IndexedProduct[]>([])
  const [isSearching, setIsSearching] = useState(false)
  const [selectedProducts, setSelectedProducts] = useState<Map<number, IndexedProduct>>(new Map())
  const [showResults, setShowResults] = useState(false)
  const [totalIndexed, setTotalIndexed] = useState<number | null>(null)
  const [initialLoading, setInitialLoading] = useState(true)
  const searchTimeoutRef = useRef<ReturnType<typeof setTimeout>>()
  const containerRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    const fetchTotal = async () => {
      try {
        const params: Record<string, unknown> = { limit: 1 }
        if (language) params.language = language
        const resp = await apiClient.get<{ data: { products: IndexedProduct[]; total: number } }>(
          'woocommerce/indexed-products',
          params,
        )
        setTotalIndexed(resp?.data?.total ?? 0)
      } catch {
        setTotalIndexed(0)
      } finally {
        setInitialLoading(false)
      }
    }
    fetchTotal()
  }, [language])

  useEffect(() => {
    if (selectedIds.length > 0 && selectedProducts.size === 0) {
      const loadSelectedProducts = async () => {
        const params: Record<string, unknown> = { limit: 100 }
        if (language) params.language = language
        try {
          const resp = await apiClient.get<{ data: { products: IndexedProduct[] } }>(
            'woocommerce/indexed-products',
            params,
          )
          const products = new Map<number, IndexedProduct>()
          for (const p of resp?.data?.products || []) {
            if (selectedIds.includes(p.id)) {
              products.set(p.id, p)
            }
          }
          for (const id of selectedIds) {
            if (!products.has(id)) {
              products.set(id, { id, name: `#${id}`, price: '', indexed: true })
            }
          }
          setSelectedProducts(products)
        } catch {
          const products = new Map<number, IndexedProduct>()
          for (const id of selectedIds) {
            products.set(id, { id, name: `#${id}`, price: '', indexed: true })
          }
          setSelectedProducts(products)
        }
      }
      loadSelectedProducts()
    }
  }, [])

  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) => {
    setIsSearching(true)
    try {
      const params: Record<string, unknown> = { limit: 20 }
      if (searchQuery.trim()) params.q = searchQuery
      if (language) params.language = language
      const resp = await apiClient.get<{ data: { products: IndexedProduct[] } }>(
        'woocommerce/indexed-products',
        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 handleFocus = useCallback(() => {
    setShowResults(true)
    if (results.length === 0 && !isSearching) {
      searchProducts(query)
    }
  }, [query, results.length, isSearching, searchProducts])

  const handleSelect = useCallback((product: IndexedProduct) => {
    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))

  if (!initialLoading && totalIndexed === 0) {
    return (
      <div>
        {label && (
          <label className="block text-sm font-medium text-gray-700 mb-2">{label}</label>
        )}
        <div className="rounded-lg border border-amber-200 bg-amber-50 p-4 text-center">
          <p className="text-sm text-amber-800 mb-2">
            {t('No indexed products found. Index your WooCommerce products in the Knowledge Base to make them available here.')}
          </p>
          <Link
            to="/knowledge-base"
            className="inline-flex items-center text-sm font-medium text-blue-600 hover:text-blue-800 hover:underline"
          >
            {t('Go to Knowledge Base')} &rarr;
          </Link>
        </div>
      </div>
    )
  }

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

      <div className="flex items-start gap-2 mb-3 p-2.5 rounded-lg bg-blue-50 border border-blue-200 text-xs text-blue-700">
        <Info className="w-3.5 h-3.5 mt-0.5 flex-shrink-0" />
        <span>
          {t('Only indexed products are shown. Manage indexing in')}{' '}
          <Link to="/knowledge-base" className="font-medium text-blue-600 hover:underline">
            {t('Knowledge Base')}
          </Link>
          {totalIndexed !== null && ` (${totalIndexed})`}
        </span>
      </div>

      <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={handleFocus}
          placeholder={placeholder || t('Search indexed 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>

      {showResults && (
        <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">
              {query.trim() ? t('No products found') : t('No indexed products available')}
            </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>
                  <div className="flex items-center gap-2 text-xs text-gray-500">
                    {product.formatted_price && <span>{product.formatted_price}</span>}
                    {product.categories && product.categories.length > 0 && (
                      <span className="truncate">
                        {product.categories.map(c => c.name).join(', ')}
                      </span>
                    )}
                  </div>
                </div>
              </button>
            ))
          )}
        </div>
      )}

      {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>
  )
}
