'use client';

import * as React from 'react';
import Fuse from 'fuse.js';
import { Search, X, Heart, Clock, List, Shuffle } from 'lucide-react';
import { cn } from '@/lib/utils/cn';
import type { ASCIIFont } from '@/types/ascii';
import { getFavorites, getRecentFonts, toggleFavorite, isFavorite } from '@/lib/storage/favorites';

export interface FontSelectorProps {
  fonts: ASCIIFont[];
  selectedFont: string;
  onSelectFont: (fontName: string) => void;
  onRandomFont?: () => void;
  className?: string;
}

type FilterType = 'all' | 'favorites' | 'recent';

const FILTERS: { value: FilterType; icon: React.ElementType; label: string }[] = [
  { value: 'all', icon: List, label: 'All' },
  { value: 'favorites', icon: Heart, label: 'Fav' },
  { value: 'recent', icon: Clock, label: 'Recent' },
];

export function FontSelector({
  fonts,
  selectedFont,
  onSelectFont,
  onRandomFont,
  className,
}: FontSelectorProps) {
  const [searchQuery, setSearchQuery] = React.useState('');
  const [filter, setFilter] = React.useState<FilterType>('all');
  const [favorites, setFavorites] = React.useState<string[]>([]);
  const [recentFonts, setRecentFonts] = React.useState<string[]>([]);
  const selectedRef = React.useRef<HTMLButtonElement>(null);

  React.useEffect(() => {
    setFavorites(getFavorites());
    setRecentFonts(getRecentFonts());
  }, []);

  // Keep selected item in view when font changes externally (e.g. random)
  React.useEffect(() => {
    selectedRef.current?.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
  }, [selectedFont]);

  const fuse = React.useMemo(
    () => new Fuse(fonts, { keys: ['name', 'fileName'], threshold: 0.3, includeScore: true }),
    [fonts]
  );

  const filteredFonts = React.useMemo(() => {
    let base = fonts;
    if (filter === 'favorites') {
      base = fonts.filter((f) => favorites.includes(f.name));
    } else if (filter === 'recent') {
      base = [...fonts.filter((f) => recentFonts.includes(f.name))].sort(
        (a, b) => recentFonts.indexOf(a.name) - recentFonts.indexOf(b.name)
      );
    }
    if (!searchQuery) return base;
    const hits = fuse.search(searchQuery).map((r) => r.item);
    return filter === 'all' ? hits : hits.filter((f) => base.includes(f));
  }, [fonts, searchQuery, fuse, filter, favorites, recentFonts]);

  const handleToggleFavorite = (fontName: string, e: React.MouseEvent) => {
    e.stopPropagation();
    toggleFavorite(fontName);
    setFavorites(getFavorites());
  };

  const emptyMessage =
    filter === 'favorites'
      ? 'No favorites yet — click ♥ to save'
      : filter === 'recent'
      ? 'No recent fonts'
      : searchQuery
      ? 'No fonts match your search'
      : 'Loading fonts…';

  return (
    <div className={cn('glass rounded-xl p-3 flex flex-col min-h-0 overflow-hidden', className)}>

      {/* ── Header ────────────────────────────────────────────── */}
      <div className="flex items-center justify-between mb-3 shrink-0">
        <span className="text-[10px] font-semibold text-muted-foreground uppercase tracking-widest">
          Fonts
        </span>
        <div className="flex items-center gap-2.5">
          <span className="text-[10px] text-muted-foreground/35 font-mono tabular-nums">
            {fonts.length}
          </span>
          {onRandomFont && (
            <button
              onClick={onRandomFont}
              className="text-muted-foreground/50 hover:text-primary transition-colors"
              title="Random font"
            >
              <Shuffle className="w-3.5 h-3.5" />
            </button>
          )}
        </div>
      </div>

      {/* ── Filter tabs ───────────────────────────────────────── */}
      <div className="flex glass rounded-lg p-0.5 gap-0.5 mb-3 shrink-0">
        {FILTERS.map(({ value, icon: Icon, label }) => (
          <button
            key={value}
            onClick={() => setFilter(value)}
            className={cn(
              'flex-1 flex items-center justify-center gap-1.5 py-1.5 rounded-md text-xs font-medium transition-all',
              filter === value
                ? 'bg-primary text-primary-foreground shadow-sm'
                : 'text-muted-foreground hover:text-foreground'
            )}
          >
            <Icon className="w-3 h-3" />
            {label}
          </button>
        ))}
      </div>

      {/* ── Search ────────────────────────────────────────────── */}
      <div className="relative mb-3 shrink-0">
        <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-3 h-3 text-muted-foreground/40 pointer-events-none" />
        <input
          type="text"
          placeholder="Search fonts…"
          value={searchQuery}
          onChange={(e) => setSearchQuery(e.target.value)}
          className="w-full bg-transparent border border-border/40 rounded-lg pl-8 pr-7 py-1.5 text-xs font-mono outline-none focus:border-primary/50 transition-colors placeholder:text-muted-foreground/30"
        />
        {searchQuery && (
          <button
            onClick={() => setSearchQuery('')}
            className="absolute right-2.5 top-1/2 -translate-y-1/2 text-muted-foreground/40 hover:text-muted-foreground transition-colors"
          >
            <X className="w-3 h-3" />
          </button>
        )}
      </div>

      {/* ── Font list ─────────────────────────────────────────── */}
      <div className="flex-1 min-h-0 overflow-y-auto scrollbar-thin scrollbar-thumb-primary/20 scrollbar-track-transparent space-y-0.5 pr-0.5">
        {filteredFonts.length === 0 ? (
          <div className="py-10 text-center">
            <p className="text-xs text-muted-foreground/35 italic">{emptyMessage}</p>
          </div>
        ) : (
          filteredFonts.map((font) => {
            const isSelected = selectedFont === font.name;
            const fav = isFavorite(font.name);
            return (
              <div
                key={font.name}
                className={cn(
                  'group flex items-center gap-1.5 rounded-lg transition-all cursor-pointer',
                  'border-l-2',
                  isSelected
                    ? 'bg-primary/10 border-primary text-primary'
                    : 'border-transparent text-foreground/65 hover:bg-primary/8 hover:text-foreground'
                )}
              >
                <button
                  ref={isSelected ? selectedRef : undefined}
                  onClick={() => onSelectFont(font.name)}
                  className="flex-1 text-left text-xs font-mono truncate px-2 py-1.5"
                >
                  {font.name}
                </button>
                <button
                  onClick={(e) => handleToggleFavorite(font.name, e)}
                  className={cn(
                    'shrink-0 pr-2 transition-all',
                    fav ? 'opacity-100' : 'opacity-0 group-hover:opacity-100'
                  )}
                  aria-label={fav ? 'Remove from favorites' : 'Add to favorites'}
                >
                  <Heart
                    className={cn(
                      'w-3 h-3 transition-colors',
                      fav ? 'fill-rose-500 text-rose-500' : 'text-muted-foreground/40 hover:text-rose-400'
                    )}
                  />
                </button>
              </div>
            );
          })
        )}
      </div>

      {/* ── Footer ────────────────────────────────────────────── */}
      <div className="mt-3 pt-2.5 border-t border-border/25 flex items-center justify-between shrink-0">
        <span className="text-[10px] text-muted-foreground/35 font-mono tabular-nums">
          {filteredFonts.length} font{filteredFonts.length !== 1 ? 's' : ''}
        </span>
        {filter === 'favorites' && (
          <span className="text-[10px] text-muted-foreground/35">{favorites.length} saved</span>
        )}
        {filter === 'recent' && (
          <span className="text-[10px] text-muted-foreground/35">{recentFonts.length} recent</span>
        )}
      </div>

    </div>
  );
}
