'use client';

import * as React from 'react';
import Fuse from 'fuse.js';
import { Input } from '@/components/ui/input';
import { Card } from '@/components/ui/card';
import {
  Empty,
  EmptyDescription,
  EmptyHeader,
  EmptyMedia,
  EmptyTitle,
} from "@/components/ui/empty"
import { Search, X, Heart, Clock, List, Shuffle } from 'lucide-react';
import { cn } from '@/lib/utils/cn';
import { Button } from '@/components/ui/button';
import type { FigletFont } from '@/types/figlet';
import { getFavorites, getRecentFonts, toggleFavorite, isFavorite } from '@/lib/storage/favorites';

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

type FilterType = 'all' | 'favorites' | '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 searchInputRef = React.useRef<HTMLInputElement>(null);

  // Load favorites and recent fonts
  React.useEffect(() => {
    setFavorites(getFavorites());
    setRecentFonts(getRecentFonts());
  }, []);

  // Initialize Fuse.js for fuzzy search
  const fuse = React.useMemo(() => {
    return new Fuse(fonts, {
      keys: ['name', 'fileName'],
      threshold: 0.3,
      includeScore: true,
    });
  }, [fonts]);

  const filteredFonts = React.useMemo(() => {
    let fontsToFilter = fonts;

    // Apply category filter
    if (filter === 'favorites') {
      fontsToFilter = fonts.filter(f => favorites.includes(f.name));
    } else if (filter === 'recent') {
      fontsToFilter = fonts.filter(f => recentFonts.includes(f.name));
      // Sort by recent order
      fontsToFilter.sort((a, b) => {
        return recentFonts.indexOf(a.name) - recentFonts.indexOf(b.name);
      });
    }

    // Apply search query
    if (!searchQuery) return fontsToFilter;

    const results = fuse.search(searchQuery);
    const searchResults = results.map(result => result.item);

    // Filter search results by category
    if (filter === 'favorites') {
      return searchResults.filter(f => favorites.includes(f.name));
    } else if (filter === 'recent') {
      return searchResults.filter(f => recentFonts.includes(f.name));
    }

    return searchResults;
  }, [fonts, searchQuery, fuse, filter, favorites, recentFonts]);

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

  return (
    <Card className={cn("flex flex-col min-h-0 overflow-hidden", className)}>
      <div className="p-6 flex flex-col flex-1 min-h-0">
        <div className="flex items-center justify-between mb-4 shrink-0">
          <h3 className="text-sm font-medium">Select Font</h3>
          {onRandomFont && (
            <Button
              variant="outline"
              size="sm"
              onClick={onRandomFont}
              title="Random font"
            >
              <Shuffle className="h-3 w-3 mr-2" />
              Random
            </Button>
          )}
        </div>

        {/* Filter Tabs */}
        <div className="flex gap-1 mb-4 p-1 bg-muted rounded-lg shrink-0">
          <button
            onClick={() => setFilter('all')}
            className={cn(
              'flex-1 flex items-center justify-center px-3 py-1.5 text-xs font-medium rounded-md transition-colors',
              filter === 'all' ? 'bg-background shadow-sm' : 'hover:bg-background/50'
            )}
          >
            <List className="h-3 w-3 mr-1.5" />
            All
          </button>
          <button
            onClick={() => setFilter('favorites')}
            className={cn(
              'flex-1 flex items-center justify-center px-3 py-1.5 text-xs font-medium rounded-md transition-colors',
              filter === 'favorites' ? 'bg-background shadow-sm' : 'hover:bg-background/50'
            )}
          >
            <Heart className="h-3 w-3 mr-1.5" />
            Favorites
          </button>
          <button
            onClick={() => setFilter('recent')}
            className={cn(
              'flex-1 flex items-center justify-center px-3 py-1.5 text-xs font-medium rounded-md transition-colors',
              filter === 'recent' ? 'bg-background shadow-sm' : 'hover:bg-background/50'
            )}
          >
            <Clock className="h-3 w-3 mr-1.5" />
            Recent
          </button>
        </div>

        {/* Search Input */}
        <div className="relative mb-4 shrink-0">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground pointer-events-none" />
          <Input
            ref={searchInputRef}
            type="text"
            placeholder="Search fonts..."
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            className="pl-9 pr-9"
          />
          {searchQuery && (
            <button
              onClick={() => setSearchQuery('')}
              className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
              aria-label="Clear search"
            >
              <X className="h-4 w-4" />
            </button>
          )}
        </div>

        {/* Font List */}
        <div className="flex-1 overflow-y-auto space-y-1 pr-2">
          {filteredFonts.length === 0 ? (
            <Empty>
              <EmptyHeader>
                <EmptyMedia variant="icon">
                  {filter === 'favorites' ? <Heart /> : (filter === 'recent' ? <Clock /> : <Search />)}
                </EmptyMedia>
                <EmptyTitle>{
                filter === 'favorites'
                  ? 'No favorite fonts yet'
                  : filter === 'recent'
                  ? 'No recent fonts'
                  : 'No fonts found'
              }</EmptyTitle>
                <EmptyDescription>
                  {
                    filter === 'favorites'
                      ? 'Click the heart icon on any font to add it to your favorites'
                      : filter === 'recent'
                      ? 'Fonts you use will appear here'
                      : searchQuery
                      ? 'Try a different search term'
                      : 'Loading fonts...'
                  }
                </EmptyDescription>
              </EmptyHeader>
            </Empty>
          ) : (
            filteredFonts.map((font) => (
              <div
                key={font.name}
                className={cn(
                  'group flex items-center gap-2 px-3 py-2 rounded-md text-sm transition-colors',
                  'hover:bg-accent hover:text-accent-foreground',
                  selectedFont === font.name && 'bg-accent text-accent-foreground font-medium'
                )}
              >
                <button
                  onClick={() => onSelectFont(font.name)}
                  className="flex-1 text-left"
                >
                  {font.name}
                </button>
                <button
                  onClick={(e) => handleToggleFavorite(font.name, e)}
                  className="p-1"
                  aria-label={isFavorite(font.name) ? 'Remove from favorites' : 'Add to favorites'}
                >
                  <Heart
                    className={cn(
                      'h-4 w-4 transition-colors',
                      isFavorite(font.name) ? 'fill-red-500 text-red-500' : 'text-muted-foreground/30 hover:text-red-500/50'
                    )}
                  />
                </button>
              </div>
            ))
          )}
        </div>

        {/* Stats */}
        <div className="mt-4 pt-4 border-t text-xs text-muted-foreground shrink-0">
          {filteredFonts.length} font{filteredFonts.length !== 1 ? 's' : ''}
          {filter === 'favorites' && ` • ${favorites.length} total favorites`}
          {filter === 'recent' && ` • ${recentFonts.length} recent`}
        </div>
      </div>
    </Card>
  );
}
