'use client';

import { Suspense, useCallback, useEffect, useState } from 'react';
import { useSearchParams } from 'next/navigation';
import Link from 'next/link';
import { AlertCircle, ChevronLeft, ChevronRight, Filter, Search, ShoppingBag, Star } from 'lucide-react';
import { useDispatch, useSelector } from 'react-redux';
import { RootState } from '@/store';
import { addToCart } from '@/store/cartSlice';
import { formatPrice } from '@/lib/currency';
import api from '@/lib/api';

interface Book {
  id: string;
  title: string;
  slug: string;
  price: number;
  discountPrice?: number | null;
  coverImage?: string | null;
  ratingAverage: number;
  authorName?: string | null;
  publisherName?: string | null;
  categoryName?: string | null;
  language?: string | null;
  stock: number;
}

interface MetadataItem { id: string; name: string; slug?: string; productCount?: number }

function BooksContent() {
  const searchParams = useSearchParams();
  const dispatch = useDispatch();
  const { currency } = useSelector((state: RootState) => state.cart);
  const [books, setBooks] = useState<Book[]>([]);
  const [categories, setCategories] = useState<MetadataItem[]>([]);
  const [authors, setAuthors] = useState<MetadataItem[]>([]);
  const [publishers, setPublishers] = useState<MetadataItem[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');
  const [pagination, setPagination] = useState({ total: 0, page: 1, limit: 24, totalPages: 1 });
  const [search, setSearch] = useState(searchParams.get('search') || '');
  const [query, setQuery] = useState(searchParams.get('search') || '');
  const [language, setLanguage] = useState('');
  // Existing header/subject links use `subject`; keep that URL contract while
  // also supporting the newer `category` parameter.
  const [category, setCategory] = useState(
    searchParams.get('category') || searchParams.get('subject') || ''
  );
  const [author, setAuthor] = useState('');
  const [publisher, setPublisher] = useState('');
  const [sort, setSort] = useState('displayOrder:asc');

  useEffect(() => {
    const timer = window.setTimeout(() => setQuery(search.trim()), 300);
    return () => window.clearTimeout(timer);
  }, [search]);

  useEffect(() => {
    Promise.all([
      api.get('/catalog/categories?limit=2000'),
      api.get('/catalog/authors?limit=2000'),
      api.get('/catalog/publishers?limit=2000'),
    ]).then(([categoryResponse, authorResponse, publisherResponse]) => {
      const loadedCategories: MetadataItem[] = categoryResponse.data.data.categories ?? [];
      setCategories(loadedCategories);
      setCategory((current) => {
        const match = loadedCategories.find(
          (item) => item.id === current || item.slug === current || item.name === current
        );
        return match?.id ?? current;
      });
      setAuthors(authorResponse.data.data.authors ?? []);
      setPublishers(publisherResponse.data.data.publishers ?? []);
    }).catch(() => setError('The catalog filters could not be loaded.'));
  }, []);

  const fetchBooks = useCallback(async () => {
    setLoading(true);
    setError('');
    try {
      const [sortBy, sortOrder] = sort.split(':');
      const params = new URLSearchParams({
        page: String(pagination.page),
        limit: String(pagination.limit),
        sortBy,
        sortOrder,
      });
      if (query) params.set('search', query);
      if (language) params.set('language', language);
      if (category) params.set('category', category);
      if (author) params.set('author', author);
      if (publisher) params.set('publisher', publisher);
      const response = await api.get(`/books?${params.toString()}`);
      setBooks(response.data.data.books ?? []);
      setPagination(response.data.data.pagination);
    } catch (requestError) {
      setBooks([]);
      setError(requestError instanceof Error ? requestError.message : 'The product catalog could not be loaded.');
    } finally {
      setLoading(false);
    }
  }, [author, category, language, pagination.limit, pagination.page, publisher, query, sort]);

  useEffect(() => { void fetchBooks(); }, [fetchBooks]);

  const changeFilter = (setter: (value: string) => void, value: string) => {
    setter(value);
    setPagination((current) => ({ ...current, page: 1 }));
  };

  return (
    <div className="mx-auto max-w-7xl space-y-8 px-4 py-10 sm:px-6 lg:px-8">
      <div>
        <h1 className="text-3xl font-extrabold text-zinc-900 dark:text-zinc-100">Browse Indian Literature</h1>
        <p className="mt-1 text-sm text-zinc-500">Search the complete Indian Books Worldwide catalog</p>
      </div>

      <div className="space-y-3 rounded-2xl border border-zinc-200 bg-white p-4 shadow-sm dark:border-zinc-800 dark:bg-zinc-900">
        <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-6">
          <label className="relative xl:col-span-2">
            <input value={search} onChange={(event) => { setSearch(event.target.value); setPagination((current) => ({ ...current, page: 1 })); }} placeholder="Search title, author, ISBN, SKU…" className="w-full rounded-xl border border-zinc-300 bg-zinc-50 py-2 pl-10 pr-4 text-sm dark:border-zinc-700 dark:bg-zinc-800" />
            <Search className="absolute left-3 top-2.5 h-4 w-4 text-zinc-400" />
          </label>
          <select value={category} onChange={(event) => changeFilter(setCategory, event.target.value)} className="rounded-xl border border-zinc-300 bg-zinc-50 px-3 py-2 text-xs dark:border-zinc-700 dark:bg-zinc-800"><option value="">All categories</option>{categories.map((item) => <option key={item.id} value={item.id}>{item.name} ({item.productCount ?? 0})</option>)}</select>
          <select value={author} onChange={(event) => changeFilter(setAuthor, event.target.value)} className="rounded-xl border border-zinc-300 bg-zinc-50 px-3 py-2 text-xs dark:border-zinc-700 dark:bg-zinc-800"><option value="">All authors</option>{authors.map((item) => <option key={item.id} value={item.id}>{item.name} ({item.productCount ?? 0})</option>)}</select>
          <select value={publisher} onChange={(event) => changeFilter(setPublisher, event.target.value)} className="rounded-xl border border-zinc-300 bg-zinc-50 px-3 py-2 text-xs dark:border-zinc-700 dark:bg-zinc-800"><option value="">All publishers</option>{publishers.map((item) => <option key={item.id} value={item.id}>{item.name} ({item.productCount ?? 0})</option>)}</select>
          <input value={language} onChange={(event) => changeFilter(setLanguage, event.target.value)} placeholder="Language" className="rounded-xl border border-zinc-300 bg-zinc-50 px-3 py-2 text-xs dark:border-zinc-700 dark:bg-zinc-800" />
        </div>
        <div className="flex flex-wrap items-center gap-3 text-xs text-zinc-500">
          <Filter className="h-4 w-4" />
          <span>{pagination.total.toLocaleString()} products</span>
          <select value={sort} onChange={(event) => changeFilter(setSort, event.target.value)} className="ml-auto rounded-lg border border-zinc-300 bg-zinc-50 px-3 py-1.5 dark:border-zinc-700 dark:bg-zinc-800">
            <option value="displayOrder:asc">Recommended</option><option value="title:asc">Title A–Z</option><option value="price:asc">Price low–high</option><option value="price:desc">Price high–low</option><option value="createdAt:desc">Newest</option>
          </select>
        </div>
      </div>

      {error && <div className="flex items-center gap-2 rounded-xl border border-red-200 bg-red-50 p-4 text-sm text-red-700"><AlertCircle className="h-4 w-4" />{error}</div>}

      {loading ? (
        <div className="grid animate-pulse grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4">{[1,2,3,4,5,6,7,8].map((item) => <div key={item} className="h-80 rounded-2xl bg-zinc-200 dark:bg-zinc-800" />)}</div>
      ) : books.length === 0 ? (
        <div className="rounded-2xl border border-zinc-200 bg-white py-16 text-center dark:border-zinc-800 dark:bg-zinc-900"><p className="font-bold">No books found</p><p className="mt-2 text-xs text-zinc-500">Try adjusting the search or filters.</p></div>
      ) : (
        <div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4">
          {books.map((book) => (
            <article key={book.id} className="group flex flex-col justify-between overflow-hidden rounded-2xl border border-zinc-200 bg-white shadow-sm transition hover:shadow-xl dark:border-zinc-800 dark:bg-zinc-900">
              <Link href={`/books/${book.slug}`} className="block flex-1">
                <div className="relative h-56 overflow-hidden bg-zinc-100 dark:bg-zinc-800">{book.coverImage ? <img src={book.coverImage} alt={book.title} className="h-full w-full object-contain transition-transform duration-300 group-hover:scale-105" /> : <div className="flex h-full items-center justify-center text-xs text-zinc-400">Image unavailable</div>}{book.language && <span className="absolute right-2 top-2 rounded bg-[#701a08] px-2 py-0.5 text-[10px] font-bold text-white">{book.language}</span>}</div>
                <div className="space-y-1.5 p-4"><span className="text-[11px] font-medium text-zinc-500">{book.authorName || 'Author not specified'}</span><h2 className="line-clamp-2 text-sm font-bold group-hover:text-[#701a08]">{book.title}</h2><p className="line-clamp-1 text-[10px] text-zinc-500">{book.publisherName || book.categoryName}</p><div className="flex items-center gap-1 text-xs text-amber-500"><Star className="h-3.5 w-3.5 fill-amber-500" /><span className="font-bold">{book.ratingAverage || 0}</span></div></div>
              </Link>
              <div className="flex items-center justify-between border-t border-zinc-100 p-4 dark:border-zinc-800"><div><span className="text-base font-extrabold">{formatPrice(book.discountPrice ?? book.price, currency)}</span>{book.discountPrice != null && <span className="ml-1.5 text-xs text-zinc-400 line-through">{formatPrice(book.price, currency)}</span>}</div><button disabled={book.stock <= 0} onClick={() => dispatch(addToCart({ id: book.id, bookId: book.id, title: book.title, price: book.price, discountPrice: book.discountPrice ?? undefined, coverImage: book.coverImage ?? undefined, stock: book.stock }))} className="rounded-xl bg-[#701a08] p-2.5 text-white disabled:cursor-not-allowed disabled:opacity-40" aria-label={`Add ${book.title} to cart`}><ShoppingBag className="h-4 w-4" /></button></div>
            </article>
          ))}
        </div>
      )}

      <div className="flex items-center justify-between"><button disabled={pagination.page <= 1} onClick={() => setPagination((current) => ({ ...current, page: current.page - 1 }))} className="inline-flex items-center gap-1 rounded-xl border px-4 py-2 text-xs font-bold disabled:opacity-40"><ChevronLeft className="h-4 w-4" /> Previous</button><span className="text-xs text-zinc-500">Page {pagination.page} of {pagination.totalPages}</span><button disabled={pagination.page >= pagination.totalPages} onClick={() => setPagination((current) => ({ ...current, page: current.page + 1 }))} className="inline-flex items-center gap-1 rounded-xl border px-4 py-2 text-xs font-bold disabled:opacity-40">Next <ChevronRight className="h-4 w-4" /></button></div>
    </div>
  );
}

export default function BooksPage() {
  return (
    <Suspense fallback={<div className="mx-auto max-w-7xl px-4 py-16"><div className="h-80 animate-pulse rounded-3xl bg-zinc-200 dark:bg-zinc-800" /></div>}>
      <BooksContent />
    </Suspense>
  );
}
