import { render, screen, fireEvent, waitFor, act } from "@testing-library/react";
import { describe, it, expect, vi, beforeEach } from "vitest";
import { CopyButton } from "@/components/ui/CopyButton";
import React from "react";
import { toast } from "sonner";

// Mock sonner toast
vi.mock("sonner", () => ({
  toast: {
    success: vi.fn(),
    error: vi.fn(),
  },
}));

describe("CopyButton", () => {
  const mockWriteText = vi.fn();

  beforeEach(() => {
    vi.clearAllMocks();
    // Mock navigator.clipboard
    Object.assign(navigator, {
      clipboard: {
        writeText: mockWriteText,
      },
    });
    mockWriteText.mockResolvedValue(undefined);
  });

  it("renders correctly with default icon", () => {
    render(<CopyButton value="test-value" />);
    const button = screen.getByRole("button");
    expect(button).toBeInTheDocument();
    // Initially should have the copy icon (sr-only text "Kopieren")
    expect(screen.getByText("Kopieren")).toBeInTheDocument();
  });

  it("copies value to clipboard and shows success state", async () => {
    render(<CopyButton value="test-value" />);
    const button = screen.getByRole("button");

    await act(async () => {
      fireEvent.click(button);
    });

    expect(mockWriteText).toHaveBeenCalledWith("test-value");

    await waitFor(() => {
      expect(toast.success).toHaveBeenCalledWith("Kopiert!");
    });

    // Should show success icon (sr-only text "Kopiert!" or state change)
    await waitFor(() => {
      expect(screen.getByText("Kopiert!")).toBeInTheDocument();
    });
  });

  it("handles copy failure", async () => {
    mockWriteText.mockRejectedValue(new Error("Failed"));
    render(<CopyButton value="test-value" />);
    const button = screen.getByRole("button");

    await act(async () => {
      fireEvent.click(button);
    });

    await waitFor(() => {
      expect(toast.error).toHaveBeenCalledWith("Fehler beim Kopieren");
    });
  });
});
