"use client";

import { useEffect, useState, useMemo } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { Button } from "@/components/ui/Button";
import { EmptyState } from "@/components/ui/EmptyState";
import { GradientSpinner } from "@/components/ui/GradientSpinner";
import { AudiobookCard } from "@/components/ui/AudiobookCard";
import { api } from "@/lib/api";
import { useAudio } from "@/lib/audio-context";
import { useAuth } from "@/lib/auth-context";
import { useToast } from "@/lib/toast-context";
import { useAudiobooksQuery } from "@/hooks/useQueries";
import {
    Book,
    ListTree,
    Shuffle,
} from "lucide-react";

interface Audiobook {
    id: string;
    title: string;
    author: string;
    narrator?: string;
    description?: string;
    coverUrl: string | null;
    duration: number;
    libraryId: string;
    series?: {
        name: string;
        sequence: string;
    } | null;
    genres?: string[];
    progress: {
        currentTime: number;
        progress: number;
        isFinished: boolean;
        lastPlayedAt: Date;
    } | null;
}

type FilterType = "all" | "listening" | "finished";
type SortType = "title" | "author" | "recent" | "series";

export default function AudiobooksPage() {
    const router = useRouter();
    const { isAuthenticated } = useAuth();
    const { toast } = useToast();
    const { currentAudiobook, pause } = useAudio();

    // Use React Query hook for audiobooks
    const { data: audiobooksData, isLoading, error } = useAudiobooksQuery();

    const [filter, setFilter] = useState<FilterType>("all");
    const [sortBy, setSortBy] = useState<SortType>("title");
    const [selectedGenre, setSelectedGenre] = useState<string | null>(null);
    const [groupBySeries, setGroupBySeries] = useState(false);
    const [itemsPerPage, setItemsPerPage] = useState<number>(50);
    const [currentPage, setCurrentPage] = useState(1);

    // Check if Audiobookshelf is configured
    const isConfigured =
        !error &&
        (!audiobooksData ||
            !("configured" in audiobooksData) ||
            audiobooksData.configured !== false);
    const audiobooks: Audiobook[] = Array.isArray(audiobooksData)
        ? audiobooksData
        : [];

    // Clear player state if Audiobookshelf is disabled
    useEffect(() => {
        if (!isConfigured && currentAudiobook) {
            pause();
            // Clear from localStorage
            if (typeof window !== "undefined") {
                localStorage.removeItem("lidify_current_audiobook");
                localStorage.removeItem("lidify_playback_type");
            }
        }
    }, [isConfigured, currentAudiobook, pause]);

    // Combine progress data with currently playing audiobook for real-time updates
    const continueListening = useMemo(() => {
        const inProgress = audiobooks.filter(
            (book) =>
                book.progress &&
                book.progress.progress > 0 &&
                !book.progress.isFinished
        );
        
        // If currently playing an audiobook that's not in the list, prepend it
        if (currentAudiobook && !inProgress.find(b => b.id === currentAudiobook.id)) {
            const currentBook = audiobooks.find(b => b.id === currentAudiobook.id);
            if (currentBook) {
                return [currentBook, ...inProgress];
            }
        }
        return inProgress;
    }, [audiobooks, currentAudiobook]);

    // Get all unique genres
    const allGenres = Array.from(
        new Set(audiobooks.flatMap((book) => book.genres || []))
    ).sort();

    const getFilteredAndSortedBooks = () => {
        // First filter by progress status
        let filtered = audiobooks;
        switch (filter) {
            case "listening":
                filtered = continueListening;
                break;
            case "finished":
                filtered = audiobooks.filter(
                    (book) => book.progress?.isFinished
                );
                break;
        }

        // Filter by genre
        if (selectedGenre) {
            filtered = filtered.filter((book) =>
                book.genres?.includes(selectedGenre)
            );
        }

        // Sort
        const sorted = [...filtered];
        switch (sortBy) {
            case "title":
                sorted.sort((a, b) => a.title.localeCompare(b.title));
                break;
            case "author":
                sorted.sort((a, b) => a.author.localeCompare(b.author));
                break;
            case "recent":
                sorted.sort((a, b) => {
                    const aTime = a.progress?.lastPlayedAt
                        ? new Date(a.progress.lastPlayedAt).getTime()
                        : 0;
                    const bTime = b.progress?.lastPlayedAt
                        ? new Date(b.progress.lastPlayedAt).getTime()
                        : 0;
                    return bTime - aTime;
                });
                break;
            case "series":
                sorted.sort((a, b) => {
                    // Series books first, then one-offs
                    if (a.series && !b.series) return -1;
                    if (!a.series && b.series) return 1;
                    if (a.series && b.series) {
                        // Same series: sort by sequence
                        if (a.series.name === b.series.name) {
                            const aSeq = parseFloat(a.series.sequence || "0");
                            const bSeq = parseFloat(b.series.sequence || "0");
                            return aSeq - bSeq;
                        }
                        // Different series: sort by name
                        return a.series.name.localeCompare(b.series.name);
                    }
                    // Both one-offs: sort by title
                    return a.title.localeCompare(b.title);
                });
                break;
        }

        return sorted;
    };

    const filteredBooks = getFilteredAndSortedBooks();
    
    // Pagination
    const totalPages = Math.ceil(filteredBooks.length / itemsPerPage);
    const paginatedBooks = useMemo(() => {
        const start = (currentPage - 1) * itemsPerPage;
        return filteredBooks.slice(start, start + itemsPerPage);
    }, [filteredBooks, currentPage, itemsPerPage]);
    
    // Reset to page 1 when filters change
    useEffect(() => {
        setCurrentPage(1);
    }, [filter, sortBy, selectedGenre, groupBySeries]);

    // Get series and standalone books for artist-style view
    const getSeriesAndStandalone = () => {
        const seriesMap = new Map<string, Audiobook[]>();
        const standalone: Audiobook[] = [];

        paginatedBooks.forEach((book) => {
            // Only treat as series if it has a series name
            if (
                book.series &&
                book.series.name &&
                book.series.name.trim() !== ""
            ) {
                const seriesName = book.series.name.trim();
                if (!seriesMap.has(seriesName)) {
                    seriesMap.set(seriesName, []);
                }
                seriesMap.get(seriesName)!.push(book);
            } else {
                standalone.push(book);
            }
        });

        // Sort each series by sequence to get first book for cover
        seriesMap.forEach((books) => {
            books.sort((a, b) => {
                const aSeq = parseFloat(a.series?.sequence || "0");
                const bSeq = parseFloat(b.series?.sequence || "0");
                return aSeq - bSeq;
            });
        });

        return { series: Array.from(seriesMap.entries()), standalone };
    };

    const { series, standalone } = getSeriesAndStandalone();

    const getCoverUrl = (coverUrl: string | null, size = 300) => {
        if (!coverUrl) return null;
        // Proxy through backend for caching
        return api.getCoverArtUrl(coverUrl, size);
    };

    // Shuffle all audiobooks
    const handleShuffleAudiobooks = () => {
        if (audiobooks.length === 0) {
            toast.error("No audiobooks to shuffle");
            return;
        }
        // Shuffle the array
        const shuffled = [...audiobooks].sort(() => Math.random() - 0.5);
        // Play the first one (audiobooks don't have a shuffle queue like tracks)
        if (shuffled[0]) {
            toast.success(`Playing random audiobook: ${shuffled[0].title}`);
            // Navigate to the audiobook
            router.push(`/audiobooks/${shuffled[0].id}`);
        }
    };

    if (isLoading) {
        return (
            <div className="flex items-center justify-center min-h-screen">
                <GradientSpinner size="md" />
            </div>
        );
    }

    if (!isConfigured) {
        return (
            <div className="min-h-screen relative overflow-hidden">
                {/* Quick gradient fade - yellow to purple */}
                <div className="absolute inset-0 pointer-events-none">
                    <div
                        className="absolute inset-0 bg-gradient-to-b from-[#ecb200]/15 via-purple-900/10 to-transparent"
                        style={{ height: "35vh" }}
                    />
                    <div
                        className="absolute inset-0 bg-[radial-gradient(ellipse_at_top_right,var(--tw-gradient-stops))] from-[#ecb200]/8 via-transparent to-transparent"
                        style={{ height: "25vh" }}
                    />
                </div>

                <div className="relative px-4 md:px-8 py-16 md:py-24">
                    {/* Title Section */}
                    <div className="text-center mb-16">
                        <h1 className="text-3xl md:text-4xl font-bold text-white mb-6 tracking-tight">
                            Audiobooks
                        </h1>
                        <p className="text-xl md:text-2xl text-gray-400 max-w-2xl mx-auto">
                            Connect Audiobookshelf to unlock your audiobook
                            library
                        </p>
                    </div>

                    {/* Setup Steps - Horizontal Cards */}
                    <div className="grid md:grid-cols-3 gap-6 mb-12">
                        <div className="bg-gradient-to-br from-[#121212] to-[#0a0a0a] rounded-xl p-6 border border-white/5 hover:border-white/10 transition-all">
                            <div className="text-4xl font-black text-purple-400/20 mb-4">
                                01
                            </div>
                            <h3 className="text-xl font-bold text-white mb-3">
                                Install Audiobookshelf
                            </h3>
                            <p className="text-gray-400 text-sm leading-relaxed">
                                Set up your own Audiobookshelf instance via
                                Docker or use an existing installation
                            </p>
                        </div>

                        <div className="bg-gradient-to-br from-[#121212] to-[#0a0a0a] rounded-xl p-6 border border-white/5 hover:border-white/10 transition-all">
                            <div className="text-4xl font-black text-purple-400/20 mb-4">
                                02
                            </div>
                            <h3 className="text-xl font-bold text-white mb-3">
                                Get API Key
                            </h3>
                            <p className="text-gray-400 text-sm leading-relaxed">
                                Settings → Users → Click your user → API Tokens
                                → Generate
                            </p>
                        </div>

                        <div className="bg-gradient-to-br from-[#121212] to-[#0a0a0a] rounded-xl p-6 border border-white/5 hover:border-white/10 transition-all">
                            <div className="text-4xl font-black text-purple-400/20 mb-4">
                                03
                            </div>
                            <h3 className="text-xl font-bold text-white mb-3">
                                Configure
                            </h3>
                            <p className="text-gray-400 text-sm leading-relaxed">
                                Enter your Audiobookshelf URL and API key in
                                Lidify settings
                            </p>
                        </div>
                    </div>

                    {/* Action Buttons */}
                    <div className="flex flex-col sm:flex-row gap-4 justify-center max-w-2xl mx-auto mb-12">
                        <Button
                            onClick={() =>
                                router.push(
                                    "/settings?tab=system#audiobookshelf"
                                )
                            }
                            className="flex-1 py-6 text-lg font-semibold"
                        >
                            Configure Audiobookshelf
                        </Button>
                        <Button
                            variant="secondary"
                            onClick={() =>
                                window.open(
                                    "https://hub.docker.com/r/advplyr/audiobookshelf",
                                    "_blank"
                                )
                            }
                            className="flex-1 py-6 text-lg font-semibold"
                        >
                            Install via Docker
                        </Button>
                    </div>

                    {/* Footer Link */}
                    <div className="text-center">
                        <p className="text-gray-500 text-sm mb-2">Need help?</p>
                        <a
                            href="https://github.com/advplyr/audiobookshelf"
                            target="_blank"
                            rel="noopener noreferrer"
                            className="text-gray-400 hover:text-white text-sm transition-colors"
                        >
                            View Documentation
                        </a>
                    </div>
                </div>
            </div>
        );
    }

    return (
        <div className="min-h-screen relative">
            {/* Quick gradient fade - yellow to purple */}
            <div className="absolute inset-0 pointer-events-none">
                <div
                    className="absolute inset-0 bg-gradient-to-b from-[#ecb200]/15 via-purple-900/10 to-transparent"
                    style={{ height: "35vh" }}
                />
                <div
                    className="absolute inset-0 bg-[radial-gradient(ellipse_at_top_right,var(--tw-gradient-stops))] from-[#ecb200]/8 via-transparent to-transparent"
                    style={{ height: "25vh" }}
                />
            </div>

            {/* Hero Section */}
            <div className="relative">
                <div className="px-4 md:px-8 py-6">
                    <h1 className="text-2xl font-bold text-white">
                        Audiobooks
                    </h1>
                </div>
            </div>

            <div className="relative px-4 md:px-8 pb-24">
                {/* Filter and Sort Controls - Mobile Optimized */}
                <div className="mb-8 space-y-3">
                    {/* First Row: Filter Pills and Shuffle */}
                    <div className="flex flex-wrap items-center gap-2">
                        <button
                            onClick={() => setFilter("all")}
                            className={`px-4 py-2 rounded-full text-sm font-semibold transition-all ${
                                filter === "all"
                                    ? "bg-white text-black"
                                    : "bg-white/5 text-gray-400 hover:bg-white/10 hover:text-white border border-white/10"
                            }`}
                        >
                            All Books
                        </button>
                        <button
                            onClick={() => setFilter("finished")}
                            className={`px-4 py-2 rounded-full text-sm font-semibold transition-all ${
                                filter === "finished"
                                    ? "bg-white text-black"
                                    : "bg-white/5 text-gray-400 hover:bg-white/10 hover:text-white border border-white/10"
                            }`}
                        >
                            Finished
                        </button>

                        {/* Shuffle Button */}
                        <button
                            onClick={handleShuffleAudiobooks}
                            className="flex items-center gap-2 px-4 py-2 bg-[#ecb200] hover:bg-[#d4a000] text-black font-medium rounded-full transition-all hover:scale-105"
                        >
                            <Shuffle className="w-4 h-4" />
                            <span className="hidden sm:inline">Random Book</span>
                        </button>

                        {/* Results Count - Desktop only */}
                        <span className="hidden md:inline text-sm text-gray-400 ml-auto">
                            {filteredBooks.length}{" "}
                            {filteredBooks.length === 1 ? "book" : "books"}
                        </span>
                    </div>

                    {/* Second Row: Sort, Series View, Genre */}
                    <div className="flex flex-wrap items-center gap-2">
                        <select
                            value={sortBy}
                            onChange={(e) =>
                                setSortBy(e.target.value as SortType)
                            }
                            className="px-4 py-2 bg-[#1a1a1a] border border-white/10 rounded-full text-white text-sm focus:outline-none focus:border-purple-500 focus:bg-[#252525] transition-all [&>option]:bg-[#1a1a1a] [&>option]:text-white"
                        >
                            <option value="title">Title</option>
                            <option value="author">Author</option>
                            <option value="recent">Recently Played</option>
                            <option value="series">Series</option>
                        </select>

                        <button
                            onClick={() => setGroupBySeries(!groupBySeries)}
                            className={`px-4 py-2 rounded-full text-sm font-semibold transition-all flex items-center gap-2 ${
                                groupBySeries
                                    ? "bg-white text-black"
                                    : "bg-white/5 text-gray-400 hover:bg-white/10 hover:text-white border border-white/10"
                            }`}
                            title="Show series as single cards (like artist view)"
                        >
                            <ListTree className="w-4 h-4" />
                            <span className="hidden sm:inline">
                                Series View
                            </span>
                        </button>

                        {allGenres.length > 0 && (
                            <select
                                value={selectedGenre || ""}
                                onChange={(e) =>
                                    setSelectedGenre(e.target.value || null)
                                }
                                className="flex-1 min-w-0 md:flex-initial md:min-w-[140px] px-4 py-2 bg-[#1a1a1a] border border-white/10 rounded-full text-white text-sm focus:outline-none focus:border-purple-500 focus:bg-[#252525] transition-all truncate [&>option]:bg-[#1a1a1a] [&>option]:text-white"
                            >
                                <option value="">All Genres</option>
                                {allGenres.map((genre) => (
                                    <option key={genre} value={genre}>
                                        {genre}
                                    </option>
                                ))}
                            </select>
                        )}

                        {/* Items per page */}
                        <select
                            value={itemsPerPage}
                            onChange={(e) => {
                                setItemsPerPage(Number(e.target.value));
                                setCurrentPage(1);
                            }}
                            className="px-4 py-2 bg-[#1a1a1a] border border-white/10 rounded-full text-white text-sm focus:outline-none focus:border-purple-500 [&>option]:bg-[#1a1a1a] [&>option]:text-white"
                        >
                            <option value={25}>25 per page</option>
                            <option value={50}>50 per page</option>
                            <option value={100}>100 per page</option>
                            <option value={250}>250 per page</option>
                        </select>
                    </div>

                    {/* Results Count - Mobile only */}
                    <div className="md:hidden text-sm text-gray-400">
                        {filteredBooks.length}{" "}
                        {filteredBooks.length === 1 ? "book" : "books"}
                    </div>
                </div>

                <div className="space-y-8">
                    {/* Continue Listening Section */}
                    {continueListening.length > 0 &&
                        filter === "all" &&
                        !groupBySeries && (
                            <section>
                                <h2 className="text-xl font-bold text-white mb-6">
                                    Continue Listening
                                </h2>
                                <div
                                    className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 2xl:grid-cols-8 3xl:grid-cols-10 gap-6"
                                    data-tv-section="continue-listening"
                                >
                                    {continueListening.map((book, index) => (
                                        <AudiobookCard
                                            key={book.id}
                                            id={book.id}
                                            title={book.title}
                                            author={book.author}
                                            coverUrl={book.coverUrl}
                                            progress={book.progress}
                                            index={index}
                                            getCoverUrl={getCoverUrl}
                                        />
                                    ))}
                                </div>
                            </section>
                        )}

                    {/* Audiobooks Grid - Series View or Individual View */}
                    {filteredBooks.length > 0 ? (
                        groupBySeries ? (
                            // Series View - ONE card per series (like artist cards)
                            <>
                                {/* Series Cards */}
                                {series.length > 0 && (
                                    <section>
                                        <h2 className="text-xl font-bold text-white mb-6">
                                            Series
                                        </h2>
                                        <div
                                            className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 2xl:grid-cols-8 3xl:grid-cols-10 gap-6"
                                            data-tv-section="series"
                                        >
                                            {series.map(
                                                ([seriesName, books], index) => {
                                                    const firstBook = books[0];
                                                    const bookCount = `${books.length} ${books.length === 1 ? "book" : "books"}`;
                                                    return (
                                                        <AudiobookCard
                                                            key={seriesName}
                                                            id={seriesName}
                                                            title={seriesName}
                                                            author={firstBook.author}
                                                            coverUrl={firstBook.coverUrl}
                                                            seriesBadge={bookCount}
                                                            index={index}
                                                            getCoverUrl={getCoverUrl}
                                                        />
                                                    );
                                                }
                                            )}
                                        </div>
                                    </section>
                                )}

                                {/* Standalone Books */}
                                {standalone.length > 0 && (
                                    <section>
                                        <h2 className="text-xl font-bold text-white mb-6">
                                            Standalone Books
                                        </h2>
                                        <div
                                            className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 2xl:grid-cols-8 3xl:grid-cols-10 gap-6"
                                            data-tv-section="standalone"
                                        >
                                            {standalone.map((book, index) => (
                                                <AudiobookCard
                                                    key={book.id}
                                                    id={book.id}
                                                    title={book.title}
                                                    author={book.author}
                                                    coverUrl={book.coverUrl}
                                                    progress={book.progress}
                                                    index={index}
                                                    getCoverUrl={getCoverUrl}
                                                />
                                            ))}
                                        </div>
                                    </section>
                                )}
                            </>
                        ) : (
                            // Ungrouped Grid - Uniform Cards
                            <div
                                className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 2xl:grid-cols-8 3xl:grid-cols-10 gap-6"
                                data-tv-section="audiobooks"
                            >
                                {paginatedBooks.map((book, index) => (
                                    <AudiobookCard
                                        key={book.id}
                                        id={book.id}
                                        title={book.title}
                                        author={book.author}
                                        coverUrl={book.coverUrl}
                                        progress={book.progress}
                                        index={index}
                                        getCoverUrl={getCoverUrl}
                                    />
                                ))}
                            </div>
                        )
                    ) : (
                        <EmptyState
                            icon={<Book className="w-12 h-12" />}
                            title={
                                filter === "listening"
                                    ? "No audiobooks in progress"
                                    : filter === "finished"
                                    ? "No finished audiobooks"
                                    : "No audiobooks found"
                            }
                            description={
                                filter === "all"
                                    ? "Add audiobooks to your Audiobookshelf library to get started"
                                    : "Start listening to some audiobooks"
                            }
                        />
                    )}

                    {/* Pagination Controls */}
                    {totalPages > 1 && (
                        <div className="flex items-center justify-center gap-2 mt-8 pt-8 border-t border-white/10">
                            <button
                                onClick={() => setCurrentPage(1)}
                                disabled={currentPage === 1}
                                className="px-3 py-2 text-sm text-gray-400 hover:text-white disabled:opacity-50 disabled:cursor-not-allowed"
                            >
                                First
                            </button>
                            <button
                                onClick={() => setCurrentPage(p => Math.max(1, p - 1))}
                                disabled={currentPage === 1}
                                className="px-3 py-2 text-sm text-gray-400 hover:text-white disabled:opacity-50 disabled:cursor-not-allowed"
                            >
                                Prev
                            </button>
                            <span className="px-4 py-2 text-sm text-white">
                                Page {currentPage} of {totalPages}
                            </span>
                            <button
                                onClick={() => setCurrentPage(p => Math.min(totalPages, p + 1))}
                                disabled={currentPage === totalPages}
                                className="px-3 py-2 text-sm text-gray-400 hover:text-white disabled:opacity-50 disabled:cursor-not-allowed"
                            >
                                Next
                            </button>
                            <button
                                onClick={() => setCurrentPage(totalPages)}
                                disabled={currentPage === totalPages}
                                className="px-3 py-2 text-sm text-gray-400 hover:text-white disabled:opacity-50 disabled:cursor-not-allowed"
                            >
                                Last
                            </button>
                        </div>
                    )}
                </div>
            </div>
        </div>
    );
}
