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

const PROVIDER_ID = "giphy";

export default function GiphyGallery() {
  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 } = useGiphy(
    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.rating, filters.order, 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.images?.original?.url,
            imageSrc: img.images?.fixed_width?.url || img.images?.downsized?.url,
            imageAlt: img.title || "GIF",
            author: {
              url: img.username ? `https://giphy.com/${img.username}` : "https://giphy.com",
              avatar: initialsAvatar(img.username || "Giphy"),
              name: img.username || "Giphy",
            },
            previewUrl: img.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) => {
        const orig = img.images?.original;
        return {
          imageSrc: orig?.url || img.images?.downsized?.url, imageAlt: img.title || "Giphy GIF", previewUrl: img.url,
          author: { url: img.user?.profile_url, avatar: img.user?.avatar_url, name: img.user?.display_name || img.username },
          importUrl: orig?.url,
          downloadOptions: [{ label: "Original", type: "original", url: orig?.url }, { label: "Downsized", type: "downsized", url: img.images?.downsized?.url }].filter(o => o.url),
          providerId: PROVIDER_ID, imageId: String(img.id), providerBadge: "Giphy", index: idx,
          gifStillUrl: img.images?.fixed_height_still?.url, gifAnimatedUrl: img.images?.fixed_height?.url || img.images?.fixed_width?.url,
        };
      });
      setPreviewImageList(list);
    }
  }, [images, setPreviewImageList]);

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

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

  const cardProps = (image) => {
    const orig = image.images?.original;
    const fixedHeight = image.images?.fixed_height;
    const fixedWidth = image.images?.fixed_width;
    const fixedHeightStill = image.images?.fixed_height_still;
    const fixedWidthStill = image.images?.fixed_width_still;
    const url = orig?.url || fixedHeight?.url || image.images?.downsized?.url;
    
    // Prefer fixed_height for display, fall back to fixed_width or original
    const animatedUrl = fixedHeight?.url || fixedWidth?.url || orig?.url;
    const stillUrl = fixedHeightStill?.url || fixedWidthStill?.url;
    
    return {
      providerId: PROVIDER_ID,
      imageId: String(image.id),
      imageData: image,
      imageSrc: url,
      imageAlt: image.title || "Giphy GIF",
      previewUrl: image.url,
      author: {
        url: image.user?.profile_url,
        avatar: image.user?.avatar_url,
        name: image.user?.display_name || image.username,
      },
      importUrl: url,
      downloadOptions: [
        ...(orig?.url ? [{ label: "Original", type: "original", url: orig.url }] : []),
        ...(fixedHeight?.url ? [{ label: "Fixed height", type: "fixed_height", url: fixedHeight.url }] : []),
        ...(fixedWidth?.url ? [{ label: "Fixed width", type: "fixed_width", url: fixedWidth.url }] : []),
      ].filter(Boolean),
      providerBadge: "Giphy",
      // Add GIF animation control (still by default, animated on hover)
      gifStillUrl: stillUrl,
      gifAnimatedUrl: animatedUrl,
    };
  };

  return (
    <div>
      <SearchBar
        value={query}
        onChange={handleSearchChange}
        placeholder="Search GIFs..."
        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} variant="list" {...cardProps(image)} />
          ))}
        </ImageList>
      ) : (
        <ImageGrid>
          {images.map((image, index) => (
            <ImageCard key={image.id} index={index} {...cardProps(image)} />
          ))}
        </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 GIFs...
        </p>
      )}

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