'use client';

import * as React from 'react';
import Fuse from 'fuse.js';
import { Input } from '@/components/ui/input';
import { Card, CardContent, CardHeader, CardTitle } 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 { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs';
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';

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)}>
      <CardHeader className="flex flex-row items-center justify-between flex-wrap gap-2 space-y-0">
        <CardTitle>Fonts</CardTitle>
        {onRandomFont && (
          <Button
            variant="outline"
            size="xs"
            onClick={onRandomFont}
            title="Random font"
          >
            <Shuffle className="h-3 w-3 mr-1" />
            Random
          </Button>
        )}
      </CardHeader>
      <CardContent className="flex flex-col flex-1 min-h-0 pt-0">
        <Tabs
          value={filter}
          onValueChange={(v) => setFilter(v as FilterType)}
          className="mb-3 shrink-0"
        >
          <TabsList className="w-full">
            <TabsTrigger value="all" className="flex-1">
              <List className="h-3 w-3" />
              All
            </TabsTrigger>
            <TabsTrigger value="favorites" className="flex-1">
              <Heart className="h-3 w-3" />
              Fav
            </TabsTrigger>
            <TabsTrigger value="recent" className="flex-1">
              <Clock className="h-3 w-3" />
              Recent
            </TabsTrigger>
          </TabsList>
        </Tabs>

        {/* Search Input */}
        <div className="relative mb-3 shrink-0">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground pointer-events-none" />
          <Input
            ref={searchInputRef}
            type="text"
            placeholder="Search fonts..."
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            className="pl-8 pr-8 h-8 text-sm"
          />
          {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-3.5 w-3.5" />
            </button>
          )}
        </div>

        {/* Font List */}
        <div className="flex-1 overflow-y-auto space-y-0.5 pr-1 scrollbar">
          {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-1 px-2 py-1.5 rounded text-xs 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 truncate"
                >
                  {font.name}
                </button>
                <button
                  onClick={(e) => handleToggleFavorite(font.name, e)}
                  className="p-0.5 opacity-0 group-hover:opacity-100 transition-opacity shrink-0"
                  aria-label={isFavorite(font.name) ? 'Remove from favorites' : 'Add to favorites'}
                >
                  <Heart
                    className={cn(
                      'h-3 w-3 transition-colors',
                      isFavorite(font.name) ? 'fill-red-500 text-red-500 !opacity-100' : 'text-muted-foreground/50 hover:text-red-500/50'
                    )}
                  />
                </button>
              </div>
            ))
          )}
        </div>

        {/* Stats */}
        <div className="mt-3 pt-3 border-t text-[10px] text-muted-foreground shrink-0">
          {filteredFonts.length} font{filteredFonts.length !== 1 ? 's' : ''}
          {filter === 'favorites' && ` · ${favorites.length} favorites`}
          {filter === 'recent' && ` · ${recentFonts.length} recent`}
        </div>
      </CardContent>
    </Card>
  );
}
