import { useState, useEffect, useRef } from 'react'
import Image from 'next/image'
import type { Article } from '@/types/nostr'
import { useAuthorsProfiles } from '@/hooks/useAuthorsProfiles'
import { generateMnemonicIcons } from '@/lib/mnemonicIcons'
import { t } from '@/lib/i18n'

export type SortOption = 'newest' | 'oldest'

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

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

interface FiltersData {
  authors: string[]
}

function useFiltersData(articles: Article[]): FiltersData {
  const authorArticleCount = new Map<string, number>()
  articles.forEach((article) => {
    if (!article.isPresentation) {
      const count = authorArticleCount.get(article.pubkey) ?? 0
      authorArticleCount.set(article.pubkey, count + 1)
    }
  })
  const authors = Array.from(authorArticleCount.keys()).filter((pubkey) => {
    const count = authorArticleCount.get(pubkey) ?? 0
    return count > 0
  })
  return {
    authors,
  }
}

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 gap-4">
      <AuthorFilter authors={data.authors} value={filters.authorPubkey} onChange={(value) => update({ authorPubkey: 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-neon-cyan">{t('filters.sort')}</h3>
      {hasActiveFilters && (
        <button onClick={onClear} className="text-sm text-neon-cyan hover:text-neon-green font-medium transition-colors">
          {t('filters.clear')}
        </button>
      )}
    </div>
  )
}

function AuthorFilter({
  authors,
  value,
  onChange,
}: {
  authors: string[]
  value: string | null
  onChange: (value: string | null) => void
}) {
  const { profiles, loading } = useAuthorsProfiles(authors)
  const [isOpen, setIsOpen] = useState(false)
  const dropdownRef = useRef<HTMLDivElement>(null)
  const buttonRef = useRef<HTMLButtonElement>(null)

  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (
        dropdownRef.current &&
        buttonRef.current &&
        !dropdownRef.current.contains(event.target as Node) &&
        !buttonRef.current.contains(event.target as Node)
      ) {
        setIsOpen(false)
      }
    }

    const handleEscape = (event: KeyboardEvent) => {
      if (event.key === 'Escape') {
        setIsOpen(false)
        buttonRef.current?.focus()
      }
    }

    if (isOpen) {
      document.addEventListener('mousedown', handleClickOutside)
      document.addEventListener('keydown', handleEscape)
    }

    return () => {
      document.removeEventListener('mousedown', handleClickOutside)
      document.removeEventListener('keydown', handleEscape)
    }
  }, [isOpen])

  const getDisplayName = (pubkey: string): string => {
    const profile = profiles.get(pubkey)
    return profile?.name ?? `${pubkey.substring(0, 8)}...${pubkey.substring(pubkey.length - 8)}`
  }

  const getPicture = (pubkey: string): string | undefined => {
    return profiles.get(pubkey)?.picture
  }

  const getMnemonicIcons = (pubkey: string): string[] => {
    return generateMnemonicIcons(pubkey)
  }

  const selectedAuthor = value ? profiles.get(value) : null
  const selectedDisplayName = value ? getDisplayName(value) : t('filters.author')

  return (
    <div className="relative">
      <label htmlFor="author-filter" className="block text-sm font-medium text-cyber-accent mb-1">
        {t('filters.author')}
      </label>
      <div className="relative" ref={dropdownRef}>
        <button
          id="author-filter"
          ref={buttonRef}
          type="button"
          onClick={() => setIsOpen(!isOpen)}
          className="w-full px-3 py-2 border border-neon-cyan/30 rounded-lg focus:ring-2 focus:ring-neon-cyan focus:border-neon-cyan bg-cyber-dark text-cyber-accent text-left flex items-center gap-2 hover:border-neon-cyan/50 transition-colors"
          aria-expanded={isOpen}
          aria-haspopup="listbox"
        >
          {value && selectedAuthor?.picture ? (
            <Image
              src={selectedAuthor.picture}
              alt={selectedDisplayName}
              width={24}
              height={24}
              className="rounded-full object-cover border border-neon-cyan/30"
            />
          ) : value ? (
            <div className="w-6 h-6 rounded-full bg-cyber-light border border-neon-cyan/30 flex items-center justify-center flex-shrink-0">
              <span className="text-xs text-neon-cyan font-medium">
                {selectedDisplayName.charAt(0).toUpperCase()}
              </span>
            </div>
          ) : null}
          <span className="flex-1 truncate text-cyber-accent">{selectedDisplayName}</span>
          {value && (
            <div className="flex items-center gap-1 flex-shrink-0">
              {getMnemonicIcons(value).map((icon, idx) => (
                <span key={idx} className="text-sm" title={`Mnemonic icon ${idx + 1}`}>
                  {icon}
                </span>
              ))}
            </div>
          )}
          <svg
            className={`w-5 h-5 text-neon-cyan transition-transform ${isOpen ? 'rotate-180' : ''}`}
            fill="none"
            stroke="currentColor"
            viewBox="0 0 24 24"
            aria-hidden="true"
          >
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
          </svg>
        </button>
        {isOpen && (
          <div
            className="absolute z-20 w-full mt-1 bg-cyber-dark border border-neon-cyan/30 rounded-lg shadow-glow-cyan max-h-60 overflow-auto"
            role="listbox"
          >
              <button
                type="button"
                onClick={() => {
                  onChange(null)
                  setIsOpen(false)
                }}
                className={`w-full px-3 py-2 text-left hover:bg-cyber-light flex items-center gap-2 transition-colors ${
                  value === null ? 'bg-neon-cyan/20 border-l-2 border-neon-cyan' : ''
                }`}
                role="option"
                aria-selected={value === null}
              >
                <span className="flex-1 text-cyber-accent">{t('filters.author')}</span>
              </button>
              {loading ? (
                <div className="px-3 py-2 text-sm text-cyber-accent/70">{t('filters.loading')}</div>
              ) : (
                authors.map((pubkey) => {
                  const displayName = getDisplayName(pubkey)
                  const picture = getPicture(pubkey)
                  const mnemonicIcons = getMnemonicIcons(pubkey)
                  const isSelected = value === pubkey

                  return (
                    <button
                      key={pubkey}
                      type="button"
                      onClick={() => {
                        onChange(pubkey)
                        setIsOpen(false)
                      }}
                      className={`w-full px-3 py-2 text-left hover:bg-cyber-light flex items-center gap-2 transition-colors ${
                        isSelected ? 'bg-neon-cyan/20 border-l-2 border-neon-cyan' : ''
                      }`}
                      role="option"
                      aria-selected={isSelected}
                    >
                      {picture ? (
                        <Image
                          src={picture}
                          alt={displayName}
                          width={24}
                          height={24}
                          className="rounded-full object-cover flex-shrink-0 border border-neon-cyan/30"
                        />
                      ) : (
                        <div className="w-6 h-6 rounded-full bg-cyber-light border border-neon-cyan/30 flex items-center justify-center flex-shrink-0">
                          <span className="text-xs text-neon-cyan font-medium">
                            {displayName.charAt(0).toUpperCase()}
                          </span>
                        </div>
                      )}
                      <span className="flex-1 truncate text-cyber-accent">{displayName}</span>
                      <div className="flex items-center gap-1 flex-shrink-0">
                        {mnemonicIcons.map((icon, idx) => (
                          <span key={idx} className="text-sm" title={`Mnemonic icon ${idx + 1}`}>
                            {icon}
                          </span>
                        ))}
                      </div>
                    </button>
                  )
                })
              )}
          </div>
        )}
      </div>
    </div>
  )
}

function SortFilter({
  value,
  onChange,
}: {
  value: SortOption
  onChange: (value: SortOption) => void
}) {
  return (
    <div>
      <label htmlFor="sort" className="block text-sm font-medium text-cyber-accent mb-1">
        {t('filters.sort')}
      </label>
      <select
        id="sort"
        value={value}
        onChange={(e) => onChange(e.target.value as SortOption)}
        className="block w-full px-3 py-2 border border-neon-cyan/30 rounded-lg focus:ring-2 focus:ring-neon-cyan focus:border-neon-cyan bg-cyber-dark text-cyber-accent hover:border-neon-cyan/50 transition-colors"
      >
        <option value="newest" className="bg-cyber-dark">{t('filters.sort.newest')}</option>
        <option value="oldest" className="bg-cyber-dark">{t('filters.sort.oldest')}</option>
      </select>
    </div>
  )
}

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

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

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

  return (
    <div className="bg-cyber-dark border border-neon-cyan/30 rounded-lg p-4 mb-6 shadow-glow-cyan">
      <FiltersHeader hasActiveFilters={hasActiveFilters} onClear={handleClearFilters} />
      <FiltersGrid data={data} filters={filters} onFiltersChange={onFiltersChange} />
    </div>
  )
}
