import type { Article } from '@/types/nostr'

export type SortOption = 'newest' | 'oldest' | 'price-low' | 'price-high'

export interface ArticleFilters {
  authorPubkey: string | null
  minPrice: number | null
  maxPrice: number | null
  sortBy: SortOption
  category: 'science-fiction' | 'scientific-research' | 'all' | null
}

interface ArticleFiltersProps {
  filters: ArticleFilters
  onFiltersChange: (filters: ArticleFilters) => void
  articles: Article[]
}

interface FiltersData {
  authors: string[]
  minAvailablePrice: number
  maxAvailablePrice: number
}

function useFiltersData(articles: Article[]): FiltersData {
  const authors = Array.from(new Map(articles.map((a) => [a.pubkey, a.pubkey])).values())
  const prices = articles.map((a) => a.zapAmount).sort((a, b) => a - b)
  return {
    authors,
    minAvailablePrice: prices[0] ?? 0,
    maxAvailablePrice: prices[prices.length - 1] ?? 1000,
  }
}

function FiltersGrid({
  data,
  filters,
  onFiltersChange,
}: {
  data: FiltersData
  filters: ArticleFilters
  onFiltersChange: (filters: ArticleFilters) => void
}) {
  const update = (patch: Partial<ArticleFilters>) => onFiltersChange({ ...filters, ...patch })

  return (
    <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
      <AuthorFilter authors={data.authors} value={filters.authorPubkey} onChange={(value) => update({ authorPubkey: value })} />
      <PriceFilter
        label="Min price (sats)"
        id="min-price"
        placeholder={`Min: ${data.minAvailablePrice}`}
        value={filters.minPrice}
        min={data.minAvailablePrice}
        max={data.maxAvailablePrice}
        onChange={(value) => update({ minPrice: value })}
      />
      <PriceFilter
        label="Max price (sats)"
        id="max-price"
        placeholder={`Max: ${data.maxAvailablePrice}`}
        value={filters.maxPrice}
        min={data.minAvailablePrice}
        max={data.maxAvailablePrice}
        onChange={(value) => update({ maxPrice: value })}
      />
      <SortFilter value={filters.sortBy} onChange={(value) => update({ sortBy: value })} />
    </div>
  )
}

function FiltersHeader({
  hasActiveFilters,
  onClear,
}: {
  hasActiveFilters: boolean
  onClear: () => void
}) {
  return (
    <div className="flex justify-between items-center mb-4">
      <h3 className="text-lg font-semibold text-gray-900">Filters & Sort</h3>
      {hasActiveFilters && (
        <button onClick={onClear} className="text-sm text-blue-600 hover:text-blue-700 font-medium">
          Clear all
        </button>
      )}
    </div>
  )
}

function AuthorFilter({
  authors,
  value,
  onChange,
}: {
  authors: string[]
  value: string | null
  onChange: (value: string | null) => void
}) {
  return (
    <div>
      <label htmlFor="author-filter" className="block text-sm font-medium text-gray-700 mb-1">
        Author
      </label>
      <select
        id="author-filter"
        value={value ?? ''}
        onChange={(e) => onChange(e.target.value === '' ? null : e.target.value)}
        className="block w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
      >
        <option value="">All authors</option>
        {authors.map((pubkey) => (
          <option key={pubkey} value={pubkey}>
            {pubkey.substring(0, 16)}...
          </option>
        ))}
      </select>
    </div>
  )
}

function PriceFilter({
  label,
  id,
  placeholder,
  value,
  min,
  max,
  onChange,
}: {
  label: string
  id: string
  placeholder: string
  value: number | null
  min: number
  max: number
  onChange: (value: number | null) => void
}) {
  return (
    <div>
      <label htmlFor={id} className="block text-sm font-medium text-gray-700 mb-1">
        {label}
      </label>
      <input
        id={id}
        type="number"
        min={min}
        max={max}
        value={value ?? ''}
        onChange={(e) => onChange(e.target.value === '' ? null : parseInt(e.target.value, 10))}
        placeholder={placeholder}
        className="block w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
      />
    </div>
  )
}

function SortFilter({
  value,
  onChange,
}: {
  value: SortOption
  onChange: (value: SortOption) => void
}) {
  return (
    <div>
      <label htmlFor="sort" className="block text-sm font-medium text-gray-700 mb-1">
        Sort by
      </label>
      <select
        id="sort"
        value={value}
        onChange={(e) => onChange(e.target.value as SortOption)}
        className="block w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
      >
        <option value="newest">Sponsoring puis date (défaut)</option>
        <option value="oldest">Plus anciens d&apos;abord</option>
        <option value="price-low">Prix : Croissant</option>
        <option value="price-high">Prix : Décroissant</option>
      </select>
    </div>
  )
}

export function ArticleFiltersComponent({
  filters,
  onFiltersChange,
  articles,
}: ArticleFiltersProps) {
  const data = useFiltersData(articles)

  const handleClearFilters = () => {
    onFiltersChange({
      authorPubkey: null,
      minPrice: null,
      maxPrice: null,
      sortBy: 'newest',
      category: 'all',
    })
  }

  const hasActiveFilters =
    filters.authorPubkey !== null ||
    filters.minPrice !== null ||
    filters.maxPrice !== null ||
    filters.sortBy !== 'newest' ||
    filters.category !== 'all'

  return (
    <div className="bg-white border border-gray-200 rounded-lg p-4 mb-6">
      <FiltersHeader hasActiveFilters={hasActiveFilters} onClear={handleClearFilters} />
      <FiltersGrid data={data} filters={filters} onFiltersChange={onFiltersChange} />
    </div>
  )
}
