import React from "react";
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import { BrandForm } from "@/components/dashboard/catalog/BrandForm";
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", () => ({
  createBrand: vi.fn(),
  updateBrand: vi.fn(),
}));

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

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

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

  it("renders correctly for new brand", () => {
    render(<BrandForm />);
    expect(screen.getByText("Neue Marke")).toBeInTheDocument();
    expect(screen.getByLabelText(/Name/i)).toBeInTheDocument();
    expect(screen.getByRole("button", { name: "Erstellen" })).toBeInTheDocument();
  });

  it("renders correctly with initial data", () => {
    const initialData = { id: 1, name: "Test Brand" };
    render(<BrandForm initialData={initialData} />);
    expect(screen.getByText("Marke bearbeiten")).toBeInTheDocument();
    expect(screen.getByDisplayValue("Test Brand")).toBeInTheDocument();
    expect(screen.getByRole("button", { name: "Aktualisieren" })).toBeInTheDocument();
  });

  it("submits createBrand when creating a new brand", async () => {
    (catalogActions.createBrand as any).mockResolvedValue({ success: true, data: { id: 1 }, message: "Success" });
    render(<BrandForm />);

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

    await waitFor(() => {
      expect(catalogActions.createBrand).toHaveBeenCalledWith({ name: "New Brand", description: "" });
      expect(mockPush).toHaveBeenCalledWith("/dashboard/brands/overview");
      expect(mockRefresh).toHaveBeenCalled();
    });
  });

  it("submits updateBrand when editing an existing brand", async () => {
    const initialData = { id: 1, name: "Old Brand" };
    (catalogActions.updateBrand as any).mockResolvedValue({ success: true, data: { id: 1 }, message: "Success" });
    render(<BrandForm initialData={initialData} />);

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

    await waitFor(() => {
      expect(catalogActions.updateBrand).toHaveBeenCalledWith({ id: 1, data: { name: "Updated Brand", description: "" } });
      expect(mockPush).toHaveBeenCalledWith("/dashboard/brands/overview");
      expect(mockRefresh).toHaveBeenCalled();
    });
  });

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

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

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