import { FormEvent, useEffect, useState } from "react";
import { Search } from "lucide-react";
import type { BookDto, JobDto } from "@readabook/shared";
import { api, getApiFallback } from "../api/client";
import { hasActiveCoverWork, isBookCoverUpdating } from "../api/types";
import { BookCard } from "../components/BookCard";
import { EmptyState, LoadingState, Panel } from "../components/ui";

export function SearchPage() {
  const [query, setQuery] = useState("");
  const [books, setBooks] = useState<BookDto[]>([]);
  const [jobs, setJobs] = useState<JobDto[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string>();

  async function loadBooks(nextQuery = query) {
    setLoading(true);
    setError(undefined);
    try {
      const [nextBooks, nextJobs] = await Promise.all([nextQuery.trim() ? api.search(nextQuery.trim()) : api.books(), api.jobs().catch(() => [])]);
      setBooks(nextBooks);
      setJobs(nextJobs);
    } catch (loadError) {
      const fallback = getApiFallback<BookDto[]>(loadError);
      setBooks(fallback ?? []);
      setError(fallback ? "Catalogue indisponible, affichage de secours." : "Recherche indisponible.");
    } finally {
      setLoading(false);
    }
  }

  const fallbackCoverLoading = hasActiveCoverWork(jobs);

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

  async function submit(event: FormEvent) {
    event.preventDefault();
    await loadBooks(query);
  }

  return (
    <div className="page-grid">
      <Panel className="span-3">
        <form className="search-form" onSubmit={submit}>
          <Search size={20} />
          <input value={query} onChange={(event) => setQuery(event.target.value)} placeholder="Titre, auteur, ISBN" />
          <button className="primary-button" type="submit">
            Chercher
          </button>
        </form>
        {error && (
          <div className="retry-row">
            <span>{error}</span>
            <button className="ghost-button" onClick={() => void loadBooks(query)}>
              Reessayer
            </button>
          </div>
        )}
      </Panel>
      {loading && !books.length ? (
        <LoadingState />
      ) : books.length ? (
        <section className="book-grid span-3">
          {books.map((book) => (
            <BookCard key={book.id} book={book} coverLoading={isBookCoverUpdating(book, fallbackCoverLoading)} />
          ))}
        </section>
      ) : (
        <Panel className="span-3">
          <EmptyState
            title={loading ? "Recherche en cours" : "Aucun specimen"}
            detail={loading ? "Le formulaire reste disponible." : "Essaie un autre terme ou relance l'indexation."}
          />
        </Panel>
      )}
    </div>
  );
}
