import { render, screen, fireEvent } from "@testing-library/react";
import { ProductPageGallery } from "./ProductPageGallery";
import { vi, describe, it, expect, beforeEach } from "vitest";
import React from "react";
import "@testing-library/jest-dom";

// Mock Next.js Image component
vi.mock("next/image", () => ({
  __esModule: true,
  default: ({ priority, fetchPriority, ...props }: any) => {
    // eslint-disable-next-line @next/next/no-img-element
    return <img {...props} alt={props.alt} />;
  },
}));

// Mock Carousel components since they might depend on complex browser APIs
vi.mock("@/components/ui/carousel", () => ({
  Carousel: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
  CarouselContent: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
  CarouselItem: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
  CarouselNext: () => <button>Next</button>,
  CarouselPrevious: () => <button>Previous</button>,
}));

describe("ProductPageGallery", () => {
  const mockImages = [
    "/image1.jpg",
    "/image2.jpg",
    "/image3.jpg",
    "/image4.jpg",
    "/image5.jpg",
    "/image6.jpg",
  ];

  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("renders the main image (first image by default)", () => {
    render(<ProductPageGallery images={mockImages} />);
    const mainImage = screen.getByAltText("Hauptbild");
    expect(mainImage).toHaveAttribute("src", "/image1.jpg");
  });

  it("renders thumbnails with correct aria-labels", () => {
    render(<ProductPageGallery images={mockImages.slice(0, 3)} />);
    expect(screen.getByLabelText("Produktbild 1 anzeigen")).toBeInTheDocument();
    expect(screen.getByLabelText("Produktbild 2 anzeigen")).toBeInTheDocument();
    expect(screen.getByLabelText("Produktbild 3 anzeigen")).toBeInTheDocument();
  });

  it("updates main image on thumbnail click", () => {
    render(<ProductPageGallery images={mockImages.slice(0, 3)} />);
    const secondThumbnail = screen.getByLabelText("Produktbild 2 anzeigen");

    fireEvent.click(secondThumbnail);

    const mainImage = screen.getByAltText("Hauptbild");
    expect(mainImage).toHaveAttribute("src", "/image2.jpg");
  });

  it("updates main image on thumbnail hover (onMouseEnter)", () => {
    render(<ProductPageGallery images={mockImages.slice(0, 3)} />);
    const thirdThumbnail = screen.getByLabelText("Produktbild 3 anzeigen");

    fireEvent.mouseEnter(thirdThumbnail);

    const mainImage = screen.getByAltText("Hauptbild");
    expect(mainImage).toHaveAttribute("src", "/image3.jpg");
  });

  it("updates main image on thumbnail focus", () => {
    render(<ProductPageGallery images={mockImages.slice(0, 3)} />);
    const secondThumbnail = screen.getByLabelText("Produktbild 2 anzeigen");

    fireEvent.focus(secondThumbnail);

    const mainImage = screen.getByAltText("Hauptbild");
    expect(mainImage).toHaveAttribute("src", "/image2.jpg");
  });

  it("uses carousel layout when there are more than 5 images", () => {
    render(<ProductPageGallery images={mockImages} />);
    expect(screen.getByText("Next")).toBeInTheDocument();
    expect(screen.getByText("Previous")).toBeInTheDocument();
  });

  it("uses static list layout when there are 5 or fewer images", () => {
    render(<ProductPageGallery images={mockImages.slice(0, 5)} />);
    expect(screen.queryByText("Next")).not.toBeInTheDocument();
    expect(screen.queryByText("Previous")).not.toBeInTheDocument();
  });

  it("applies active ring class to the selected thumbnail", () => {
    render(<ProductPageGallery images={mockImages.slice(0, 3)} />);
    const firstThumbnail = screen.getByLabelText("Produktbild 1 anzeigen");
    const secondThumbnail = screen.getByLabelText("Produktbild 2 anzeigen");

    expect(firstThumbnail).toHaveClass("ring-2 ring-primary");
    expect(secondThumbnail).not.toHaveClass("ring-2 ring-primary");

    fireEvent.click(secondThumbnail);

    expect(firstThumbnail).not.toHaveClass("ring-2 ring-primary");
    expect(secondThumbnail).toHaveClass("ring-2 ring-primary");
  });
});
