"use client";

import React, { useEffect, useState } from 'react';
import { useStore } from '@/lib/store';
import { Copy, Sparkles, RefreshCw, Loader2, Image as ImageIcon } from 'lucide-react';
import { cn } from '@/lib/utils';
import { Prompt, PromptCache } from '@/lib/types';
import { motion, AnimatePresence } from 'framer-motion';

export function PromptLibrary({ onSelect }: { onSelect?: (prompt: string) => void }) {
    const { setPrompt, settings } = useStore();
    const [prompts, setPrompts] = useState<Prompt[]>([]);
    const [loading, setLoading] = useState(true);
    const [generating, setGenerating] = useState(false);
    const [selectedCategory, setSelectedCategory] = useState<string>('All');
    const [selectedSource, setSelectedSource] = useState<string>('All');
    const [searchTerm, setSearchTerm] = useState('');
    const [sortMode, setSortMode] = useState<'all' | 'latest' | 'history' | 'foryou'>('all');

    const fetchPrompts = async () => {
        setLoading(true);
        try {
            const res = await fetch('/api/prompts');
            if (res.ok) {
                const data: PromptCache = await res.json();
                setPrompts(data.prompts);
            }
        } catch (error) {
            console.error("Failed to fetch prompts", error);
        } finally {
            setLoading(false);
        }
    };

    const syncPrompts = async () => {
        setLoading(true);
        try {
            const syncRes = await fetch('/api/prompts/sync', { method: 'POST' });
            if (!syncRes.ok) throw new Error('Sync failed');
            await fetchPrompts();
        } catch (error) {
            console.error("Failed to sync prompts", error);
        } finally {
            setLoading(false);
        }
    };

    const generateMissingPreviews = async () => {
        if (!settings.whiskCookies) {
            alert("Please set Whisk Cookies in Settings first!");
            return;
        }

        setGenerating(true);
        try {
            // Find prompts without images
            const missing = prompts.filter(p => !p.images || p.images.length === 0);
            console.log(`Found ${missing.length} prompts without images.`);

            for (const prompt of missing) {
                try {
                    console.log(`Requesting preview for: ${prompt.title}`);

                    const res = await fetch('/api/prompts/generate', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({
                            id: prompt.id,
                            prompt: prompt.prompt,
                            cookies: settings.whiskCookies
                        })
                    });

                    if (res.ok) {
                        const { url } = await res.json();
                        setPrompts(prev => prev.map(p =>
                            p.id === prompt.id ? { ...p, images: [url, ...(p.images || [])] } : p
                        ));
                    } else {
                        const err = await res.json();
                        if (res.status === 422) {
                            console.warn(`Skipped unsafe prompt "${prompt.title}": ${err.error}`);
                        } else {
                            console.error('API Error:', err);
                        }
                    }

                    // Delay is still good to prevent flooding backend/google
                    await new Promise(r => setTimeout(r, 2000));

                } catch (error) {
                    console.error(`Failed to generate for ${prompt.id}:`, error);
                }
            }
        } catch (e) {
            console.error("Generation process failed:", e);
        } finally {
            setGenerating(false);
        }
    };

    useEffect(() => {
        fetchPrompts();
    }, []);

    const handleSelect = async (p: Prompt) => {
        setPrompt(p.prompt);
        if (onSelect) onSelect(p.prompt);

        // Track usage
        try {
            await fetch('/api/prompts/use', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ id: p.id })
            });
            // Optimistic update
            setPrompts(prev => prev.map(item =>
                item.id === p.id
                    ? { ...item, useCount: (item.useCount || 0) + 1, lastUsedAt: Date.now() }
                    : item
            ));
        } catch (e) {
            console.error("Failed to track usage", e);
        }
    };

    // Derived State
    const filteredPrompts = prompts.filter(p => {
        const matchesSearch = p.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
            p.prompt.toLowerCase().includes(searchTerm.toLowerCase());
        const matchesCategory = selectedCategory === 'All' || p.category === selectedCategory;
        const matchesSource = selectedSource === 'All' || p.source === selectedSource;
        return matchesSearch && matchesCategory && matchesSource;
    }).sort((a, b) => {
        if (sortMode === 'latest') {
            return (b.createdAt || 0) - (a.createdAt || 0);
        }
        if (sortMode === 'history') {
            return (b.lastUsedAt || 0) - (a.lastUsedAt || 0);
        }
        return 0; // Default order (or ID)
    });

    const displayPrompts = () => {
        if (sortMode === 'history') {
            return filteredPrompts.filter(p => (p.useCount || 0) > 0);
        }
        if (sortMode === 'foryou') {
            // Calculate top categories
            const categoryCounts: Record<string, number> = {};
            prompts.filter(p => (p.useCount || 0) > 0).forEach(p => {
                categoryCounts[p.category] = (categoryCounts[p.category] || 0) + 1;
            });
            const topCategories = Object.entries(categoryCounts)
                .sort(([, a], [, b]) => b - a)
                .slice(0, 3)
                .map(([cat]) => cat);

            if (topCategories.length === 0) return filteredPrompts; // No history yet

            return filteredPrompts.filter(p => topCategories.includes(p.category));
        }
        return filteredPrompts;
    };

    const finalPrompts = displayPrompts();

    const uniqueCategories = ['All', ...Array.from(new Set(prompts.map(p => p.category)))].filter(Boolean);
    const uniqueSources = ['All', ...Array.from(new Set(prompts.map(p => p.source)))].filter(Boolean);

    return (
        <div className="max-w-6xl mx-auto p-4 md:p-8 space-y-8 pb-32">
            <div className="flex flex-col md:flex-row md:items-center justify-between gap-4">
                <div className="flex items-center gap-3">
                    <div className="p-3 bg-primary/10 rounded-xl text-primary">
                        <Sparkles className="h-6 w-6" />
                    </div>
                    <div>
                        <h2 className="text-2xl font-bold">Prompt Library</h2>
                        <p className="text-muted-foreground">Curated inspiration from the community.</p>
                    </div>
                </div>
                <div className="flex items-center gap-2">
                    <button
                        onClick={generateMissingPreviews}
                        disabled={generating}
                        className={cn(
                            "p-2 hover:bg-secondary rounded-full transition-colors",
                            generating && "animate-pulse text-yellow-500"
                        )}
                        title="Auto-Generate Missing Previews"
                    >
                        <ImageIcon className="h-5 w-5" />
                    </button>

                    <button
                        onClick={syncPrompts}
                        disabled={loading}
                        className="p-2 hover:bg-secondary rounded-full transition-colors"
                        title="Sync from GitHub"
                    >
                        <RefreshCw className={cn("h-5 w-5", loading && "animate-spin")} />
                    </button>
                    <input
                        type="text"
                        placeholder="Search prompts..."
                        className="px-4 py-2 rounded-lg bg-card border focus:border-primary focus:outline-none w-full md:w-64"
                        value={searchTerm}
                        onChange={(e) => setSearchTerm(e.target.value)}
                    />
                </div>
            </div>

            {generating && (
                <div className="bg-primary/10 border border-primary/20 text-primary p-4 rounded-xl flex items-center gap-3 animate-in fade-in slide-in-from-top-2">
                    <Loader2 className="h-5 w-5 animate-spin" />
                    <span className="font-medium">Generating preview images for library prompts... This may take a while.</span>
                </div>
            )}

            {/* Smart Tabs */}
            <div className="flex items-center gap-1 bg-secondary/30 p-1 rounded-xl w-fit">
                {(['all', 'latest', 'history', 'foryou'] as const).map(mode => (
                    <button
                        key={mode}
                        onClick={() => setSortMode(mode)}
                        className={cn(
                            "px-4 py-2 rounded-lg text-sm font-medium transition-all capitalize",
                            sortMode === mode
                                ? "bg-background text-foreground shadow-sm"
                                : "text-muted-foreground hover:text-foreground hover:bg-background/50"
                        )}
                    >
                        {mode === 'foryou' ? 'For You' : mode}
                    </button>
                ))}
            </div>

            {/* Sub-Categories (only show if NOT history/foryou to keep clean? Or keep it?) */}
            {sortMode === 'all' && (
                <div className="flex flex-wrap gap-2">
                    {uniqueCategories.map(cat => (
                        <button
                            key={cat}
                            onClick={() => setSelectedCategory(cat)}
                            className={cn(
                                "px-4 py-2 rounded-full text-sm font-medium transition-colors",
                                selectedCategory === cat
                                    ? "bg-primary text-primary-foreground"
                                    : "bg-card hover:bg-secondary text-muted-foreground"
                            )}
                        >
                            {cat}
                        </button>
                    ))}
                </div>
            )}

            {/* Source Filter */}
            <div className="flex flex-wrap gap-2 items-center">
                <span className="text-sm font-medium text-muted-foreground mr-2">Sources:</span>
                {uniqueSources.map(source => (
                    <button
                        key={source}
                        onClick={() => setSelectedSource(source)}
                        className={cn(
                            "px-3 py-1 rounded-full text-xs font-medium transition-colors border",
                            selectedSource === source
                                ? "bg-primary text-primary-foreground border-primary"
                                : "bg-card hover:bg-secondary text-muted-foreground border-secondary"
                        )}
                    >
                        {source}
                    </button>
                ))}
            </div>

            {loading && !prompts.length ? (
                <div className="flex justify-center py-20">
                    <Loader2 className="h-8 w-8 animate-spin text-primary" />
                </div>
            ) : (
                <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
                    <AnimatePresence mode="popLayout">
                        {finalPrompts.map((p) => (
                            <motion.div
                                key={p.id}
                                layout
                                initial={{ opacity: 0, scale: 0.9 }}
                                animate={{ opacity: 1, scale: 1 }}
                                exit={{ opacity: 0, scale: 0.9 }}
                                className="group relative flex flex-col bg-card border rounded-xl overflow-hidden hover:border-primary/50 transition-all hover:shadow-lg"
                            >
                                {p.images && p.images.length > 0 ? (
                                    <div className="aspect-video relative overflow-hidden bg-secondary/50">
                                        <img
                                            src={p.images[0]}
                                            alt={p.title}
                                            className="object-cover w-full h-full transition-transform group-hover:scale-105"
                                            loading="lazy"
                                        />
                                    </div>
                                ) : (
                                    <div className="aspect-video bg-gradient-to-br from-secondary to-background p-4 flex items-center justify-center text-muted-foreground/20">
                                        <Sparkles className="h-12 w-12" />
                                    </div>
                                )}

                                <div className="p-4 flex flex-col flex-1 gap-3">
                                    <div className="flex justify-between items-start gap-2">
                                        <h3 className="font-semibold line-clamp-1" title={p.title}>{p.title}</h3>
                                        <span className="text-xs px-2 py-0.5 rounded-full bg-secondary text-muted-foreground whitespace-nowrap">
                                            {p.source}
                                        </span>
                                    </div>

                                    <p className="text-sm text-muted-foreground line-clamp-3 flex-1 font-mono bg-secondary/30 p-2 rounded">
                                        {p.prompt}
                                    </p>

                                    <div className="flex items-center justify-between pt-2 border-t mt-auto">
                                        <button
                                            onClick={() => handleSelect(p)}
                                            className="text-xs font-medium text-primary hover:underline flex items-center gap-1"
                                        >
                                            Use Prompt
                                        </button>
                                        <button
                                            onClick={() => navigator.clipboard.writeText(p.prompt)}
                                            className="p-1.5 text-muted-foreground hover:text-primary transition-colors"
                                            title="Copy to clipboard"
                                        >
                                            <Copy className="h-4 w-4" />
                                        </button>
                                    </div>
                                </div>
                            </motion.div>
                        ))}
                    </AnimatePresence>
                </div>
            )}

            {!loading && finalPrompts.length === 0 && (
                <div className="text-center py-20 text-muted-foreground">
                    {sortMode === 'history' ? "No prompts used yet." : "No prompts found."}
                </div>
            )}
        </div>
    );
}
