import React, { useState, useRef, useEffect } from "react";
import { useDebounce } from "../../../hooks/useDebounce";
import { useInfiniteScroll } from "../../../hooks/useInfiniteScroll";
import { useOpenverse } from "../../../hooks/useOpenverse";
import { useGenerator } from "../../../context/GeneratorContext";
import {
  SearchBar,
  ImageCard,
  ImageGrid,
  ImageList,
  ImageSkeleton,
  EmptyState,
  ErrorMessage,
} from "../../shared";
import { initialsAvatar } from "../../../utils/helpers";

const PROVIDER_ID = "openverse";

export default function OpenverseGallery() {
  const [query, setQuery] = useState("");
  const debouncedQuery = useDebounce(query, 500);
  const { viewMode, itemsPerPage, loadMoreMode, getFilters, selectAll, setPreviewImageList } = useGenerator();
  const filters = getFilters(PROVIDER_ID);
  const hasMoreRef = useRef(true);
  const loadingRef = useRef(false);
  const { page, loadMore, resetPage, observerTarget } = useInfiniteScroll(1, {
    hasMoreRef,
    loadingRef,
  });
  const { images, loading, scrollLoading, error, hasMore } = useOpenverse(
    debouncedQuery,
    page,
    filters,
    itemsPerPage
  );
  useEffect(() => {
    hasMoreRef.current = loadMoreMode === "auto" ? hasMore : false;
    loadingRef.current = scrollLoading;
  }, [hasMore, scrollLoading, loadMoreMode]);

  // Reset page when filters or settings change
  useEffect(() => {
    resetPage(1);
  }, [filters.license, filters.source, filters.orientation, itemsPerPage, resetPage]);

  // Handle bulk select all
  useEffect(() => {
    const handleBulkSelect = (e) => {
      if (e.detail.providerId === PROVIDER_ID && images.length > 0) {
        const imageData = {};
        images.forEach((img) => {
          const key = `${PROVIDER_ID}:${img.id}`;
          imageData[key] = {
            importUrl: img.url,
            imageSrc: img.thumbnail || img.url,
            imageAlt: img.title || "Openverse image",
            author: {
              url: img.creator_url,
              avatar: initialsAvatar(img.creator || "Unknown"),
              name: img.creator || "Unknown",
            },
            previewUrl: img.foreign_landing_url,
          };
        });
        selectAll(PROVIDER_ID, images.map((img) => String(img.id)), imageData);
      }
    };
    window.addEventListener('bulkSelectAll', handleBulkSelect);
    return () => window.removeEventListener('bulkSelectAll', handleBulkSelect);
  }, [images, selectAll]);

  useEffect(() => {
    if (images.length > 0) {
      const list = images.map((img, idx) => ({
        imageSrc: img.url, imageAlt: img.title || "Openverse image", previewUrl: img.foreign_landing_url,
        author: { url: img.creator_url, avatar: initialsAvatar(img.creator || "Unknown"), name: img.creator || "Unknown" },
        importUrl: img.url,
        downloadOptions: [{ label: "Original", url: img.url }].filter(o => o.url),
        providerId: PROVIDER_ID, imageId: String(img.id), providerBadge: "Openverse", index: idx,
      }));
      setPreviewImageList(list);
    }
  }, [images, setPreviewImageList]);

  const handleSearchChange = (value) => {
    setQuery(value);
    resetPage(1);
  };

  const isEmpty = !loading && !error && images.length === 0;

  return (
    <div>
      <SearchBar
        value={query}
        onChange={handleSearchChange}
        placeholder="Search Openverse (free, open-licensed images)..."
        showSubmitButton={true}
        providerId={PROVIDER_ID}
        isSearching={loading && debouncedQuery.length > 0}
      />

      <ErrorMessage message={error} />

      {loading ? (
        <ImageSkeleton variant={viewMode} />
      ) : isEmpty ? (
        <EmptyState variant="noResults" query={debouncedQuery || undefined} />
      ) : viewMode === "list" ? (
        <ImageList>
          {images.map((image, index) => (
            <ImageCard
              key={image.id}
              index={index}
              providerId={PROVIDER_ID}
              imageId={String(image.id)}
              imageData={image}
              imageSrc={image.url}
              imageAlt={image.title || "Openverse image"}
              previewUrl={image.foreign_landing_url || image.detail_url}
              author={{
                url: image.creator_url,
                avatar: initialsAvatar(image.creator || "Openverse"),
                name: image.creator,
              }}
              importUrl={image.url}
              downloadOptions={[
                { label: "Original", type: "original", url: image.url },
                ...(image.thumbnail ? [{ label: "Thumbnail", type: "thumb", url: image.thumbnail }] : []),
              ]}
              variant="list"
              providerBadge="Openverse"
            />
          ))}
        </ImageList>
      ) : (
        <ImageGrid>
          {images.map((image, index) => (
            <ImageCard
              key={image.id}
              index={index}
              providerId={PROVIDER_ID}
              imageId={String(image.id)}
              imageData={image}
              imageSrc={image.url}
              imageAlt={image.title || "Openverse image"}
              previewUrl={image.foreign_landing_url || image.detail_url}
              author={{
                url: image.creator_url,
                avatar: initialsAvatar(image.creator || "Openverse"),
                name: image.creator,
              }}
              importUrl={image.url}
              downloadOptions={[
                { label: "Original", type: "original", url: image.url },
                ...(image.thumbnail ? [{ label: "Thumbnail", type: "thumb", url: image.thumbnail }] : []),
              ]}
              providerBadge="Openverse"
            />
          ))}
        </ImageGrid>
      )}

      {loadMoreMode === "auto" && <div ref={observerTarget} className="h-4" aria-hidden="true" />}

      {loadMoreMode === "manual" && !loading && hasMore && images.length > 0 && (
        <div className="text-center mt-6">
          <button
            type="button"
            onClick={loadMore}
            disabled={scrollLoading}
            className="px-5 py-2.5 text-sm font-medium text-white rounded-xl bg-gray-800 hover:bg-gray-900 disabled:opacity-50"
          >
            {scrollLoading ? "Loading more..." : "Load More"}
          </button>
        </div>
      )}

      {scrollLoading && (
        <p className="text-center mt-4 text-sm text-gray-500" aria-live="polite">
          Loading more images...
        </p>
      )}

      {!loading && !scrollLoading && images.length > 0 && !hasMore && (
        <p className="text-center mt-4 text-sm text-gray-500">No more results.</p>
      )}
    </div>
  );
}
