import React from "react";
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import { AttributeForm } from "@/components/dashboard/catalog/AttributeForm";
import { describe, it, expect, vi, beforeEach } from "vitest";
import * as catalogActions from "@/actions/catalog";
import { useRouter } from "next/navigation";

// Mock next/navigation
vi.mock("next/navigation", () => ({
  useRouter: vi.fn(),
}));

// Mock catalog actions
vi.mock("@/actions/catalog", () => ({
  createAttribute: vi.fn(),
  updateAttribute: vi.fn(),
}));

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

describe("AttributeForm", () => {
  const mockPush = vi.fn();
  const mockRefresh = vi.fn();
  const mockBack = vi.fn();

  beforeEach(() => {
    vi.clearAllMocks();
    (useRouter as any).mockReturnValue({
      push: mockPush,
      refresh: mockRefresh,
      back: mockBack,
    });
  });

  it("renders correctly for new attribute", () => {
    render(<AttributeForm />);
    expect(screen.getByText("Neues Attribut")).toBeInTheDocument();
    expect(screen.getByLabelText(/Name/i)).toBeInTheDocument();
    expect(screen.getByRole("button", { name: "Erstellen" })).toBeInTheDocument();
  });

  it("renders correctly with initial data", () => {
    const initialData = { id: "00000000-0000-0000-0000-000000000001", name: "Test Attribute", type: "text" as const };
    render(<AttributeForm initialData={initialData} />);
    expect(screen.getByText("Attribut bearbeiten")).toBeInTheDocument();
    expect(screen.getByDisplayValue("Test Attribute")).toBeInTheDocument();
    expect(screen.getByRole("button", { name: "Aktualisieren" })).toBeInTheDocument();
  });

  it("submits createAttribute when creating a new attribute", async () => {
    (catalogActions.createAttribute as any).mockResolvedValue({ success: true, data: { id: "00000000-0000-0000-0000-000000000001" } });
    render(<AttributeForm />);

    fireEvent.change(screen.getByLabelText(/Name/i), { target: { value: "New Attribute" } });
    fireEvent.click(screen.getByRole("button", { name: "Erstellen" }));

    await waitFor(() => {
      expect(catalogActions.createAttribute).toHaveBeenCalledWith({ name: "New Attribute", type: "text" });
      expect(mockPush).toHaveBeenCalledWith("/dashboard/attributes/overview");
      expect(mockRefresh).toHaveBeenCalled();
    });
  });

  it("submits updateAttribute when editing an existing attribute", async () => {
    const initialData = { id: "00000000-0000-0000-0000-000000000001", name: "Old Attribute", type: "text" as const };
    (catalogActions.updateAttribute as any).mockResolvedValue({ success: true, data: { id: "00000000-0000-0000-0000-000000000001" } });
    render(<AttributeForm initialData={initialData} />);

    fireEvent.change(screen.getByLabelText(/Name/i), { target: { value: "Updated Attribute" } });
    fireEvent.click(screen.getByRole("button", { name: "Aktualisieren" }));

    await waitFor(() => {
      expect(catalogActions.updateAttribute).toHaveBeenCalledWith({ 
        id: "00000000-0000-0000-0000-000000000001", 
        data: { name: "Updated Attribute" } 
      });
      expect(mockPush).toHaveBeenCalledWith("/dashboard/attributes/overview");
      expect(mockRefresh).toHaveBeenCalled();
    });
  });

  it("shows error toast on failure", async () => {
    (catalogActions.createAttribute as any).mockResolvedValue({ success: false, error: "Fail", code: 400 });
    render(<AttributeForm />);

    fireEvent.change(screen.getByLabelText(/Name/i), { target: { value: "New Attribute" } });
    fireEvent.click(screen.getByRole("button", { name: "Erstellen" }));

    const { toast } = await import("sonner");
    await waitFor(() => {
      expect(toast.error).toHaveBeenCalledWith("Fail");
    });
  });

  it("calls router.push when cancel button is clicked", () => {
    render(<AttributeForm />);
    fireEvent.click(screen.getByRole("button", { name: "Abbrechen" }));
    expect(mockPush).toHaveBeenCalledWith("/dashboard/attributes/overview");
  });
});
