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

const PROVIDER_ID = "wikimedia";

export default function WikimediaGallery() {
  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 } = useWikimedia(
    debouncedQuery,
    page,
    filters,
    itemsPerPage
  );

  useEffect(() => {
    hasMoreRef.current = loadMoreMode === "auto" ? hasMore : false;
    loadingRef.current = scrollLoading;
  }, [hasMore, scrollLoading, loadMoreMode]);

  useEffect(() => {
    resetPage(1);
  }, [itemsPerPage, filters.mediaType, filters.sort, resetPage]);

  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 || img.description || "Wikimedia image",
            author: {
              url: img.page_url,
              avatar: initialsAvatar(img.author || "Wikimedia"),
              name: img.author || "Wikimedia contributor",
            },
            previewUrl: img.page_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 || img.description || "Wikimedia image",
        previewUrl: img.page_url,
        author: {
          url: img.page_url,
          avatar: initialsAvatar(img.author || "Wikimedia"),
          name: img.author || "Wikimedia contributor",
        },
        importUrl: img.url,
        downloadOptions: [
          { label: "Original", type: "original", url: img.url },
          { label: "Preview", type: "preview", url: img.thumbnail },
        ].filter((o) => o.url),
        providerId: PROVIDER_ID,
        imageId: String(img.id),
        providerBadge: "Wikimedia",
        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 Wikimedia Commons 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.thumbnail || image.url}
              imageAlt={image.title || image.description || "Wikimedia image"}
              previewUrl={image.page_url}
              author={{
                url: image.page_url,
                avatar: initialsAvatar(image.author || "Wikimedia"),
                name: image.author || "Wikimedia contributor",
              }}
              importUrl={image.url}
              downloadOptions={[
                { label: "Original", type: "original", url: image.url },
                { label: "Preview", type: "preview", url: image.thumbnail },
              ].filter((o) => o.url)}
              variant="list"
              providerBadge="Wikimedia"
            />
          ))}
        </ImageList>
      ) : (
        <ImageGrid>
          {images.map((image, index) => (
            <ImageCard
              key={image.id}
              index={index}
              providerId={PROVIDER_ID}
              imageId={String(image.id)}
              imageData={image}
              imageSrc={image.thumbnail || image.url}
              imageAlt={image.title || image.description || "Wikimedia image"}
              previewUrl={image.page_url}
              author={{
                url: image.page_url,
                avatar: initialsAvatar(image.author || "Wikimedia"),
                name: image.author || "Wikimedia contributor",
              }}
              importUrl={image.url}
              downloadOptions={[
                { label: "Original", type: "original", url: image.url },
                { label: "Preview", type: "preview", url: image.thumbnail },
              ].filter((o) => o.url)}
              providerBadge="Wikimedia"
            />
          ))}
        </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>
  );
}
