import { describe, expect, it, vi } from "vitest";
import { render, screen } from "~/test-utils.js";
import userEvent from "@testing-library/user-event";
import { BatchActionBar } from "./BatchActionBar.js";

describe("BatchActionBar", () => {
  describe("rendering", () => {
    it("renders nothing when count is 0", () => {
      const { container } = render(<BatchActionBar count={0} actions={[]} onClear={vi.fn()} />);
      expect(container).toBeEmptyDOMElement();
    });

    it("renders the bar when count is greater than 0", () => {
      render(<BatchActionBar count={3} actions={[]} onClear={vi.fn()} />);
      expect(screen.getByText("3 selected")).toBeInTheDocument();
    });

    it("displays the correct count", () => {
      render(<BatchActionBar count={42} actions={[]} onClear={vi.fn()} />);
      expect(screen.getByText("42 selected")).toBeInTheDocument();
    });

    it("renders action buttons", () => {
      const actions = [
        { label: "Edit", onClick: vi.fn() },
        { label: "Archive", onClick: vi.fn() },
      ];
      render(<BatchActionBar count={2} actions={actions} onClear={vi.fn()} />);
      expect(screen.getByRole("button", { name: "Edit" })).toBeInTheDocument();
      expect(screen.getByRole("button", { name: "Archive" })).toBeInTheDocument();
    });

    it("renders the Clear button", () => {
      render(<BatchActionBar count={1} actions={[]} onClear={vi.fn()} />);
      expect(screen.getByRole("button", { name: "Clear" })).toBeInTheDocument();
    });
  });

  describe("action variants", () => {
    it("applies danger styling to actions with variant='danger'", () => {
      const actions = [{ label: "Delete", onClick: vi.fn(), variant: "danger" as const }];
      render(<BatchActionBar count={1} actions={actions} onClear={vi.fn()} />);
      const btn = screen.getByRole("button", { name: "Delete" });
      expect(btn.className).toContain("bg-red-600");
    });

    it("applies default styling to actions without a variant", () => {
      const actions = [{ label: "Edit", onClick: vi.fn() }];
      render(<BatchActionBar count={1} actions={actions} onClear={vi.fn()} />);
      const btn = screen.getByRole("button", { name: "Edit" });
      expect(btn.className).toContain("bg-white/10");
    });

    it("applies default styling to actions with variant='default'", () => {
      const actions = [{ label: "Edit", onClick: vi.fn(), variant: "default" as const }];
      render(<BatchActionBar count={1} actions={actions} onClear={vi.fn()} />);
      const btn = screen.getByRole("button", { name: "Edit" });
      expect(btn.className).toContain("bg-white/10");
    });
  });

  describe("disabled state", () => {
    it("disables an action button when disabled prop is true", () => {
      const actions = [{ label: "Export", onClick: vi.fn(), disabled: true }];
      render(<BatchActionBar count={1} actions={actions} onClear={vi.fn()} />);
      expect(screen.getByRole("button", { name: "Export" })).toBeDisabled();
    });

    it("enables an action button when disabled prop is false", () => {
      const actions = [{ label: "Export", onClick: vi.fn(), disabled: false }];
      render(<BatchActionBar count={1} actions={actions} onClear={vi.fn()} />);
      expect(screen.getByRole("button", { name: "Export" })).not.toBeDisabled();
    });

    it("does not fire onClick when action button is disabled", async () => {
      const user = userEvent.setup();
      const handleClick = vi.fn();
      const actions = [{ label: "Export", onClick: handleClick, disabled: true }];
      render(<BatchActionBar count={1} actions={actions} onClear={vi.fn()} />);
      await user.click(screen.getByRole("button", { name: "Export" }));
      expect(handleClick).not.toHaveBeenCalled();
    });
  });

  describe("interactions", () => {
    it("calls action onClick when an action button is clicked", async () => {
      const user = userEvent.setup();
      const handleClick = vi.fn();
      const actions = [{ label: "Edit", onClick: handleClick }];
      render(<BatchActionBar count={1} actions={actions} onClear={vi.fn()} />);
      await user.click(screen.getByRole("button", { name: "Edit" }));
      expect(handleClick).toHaveBeenCalledOnce();
    });

    it("calls onClear when the Clear button is clicked", async () => {
      const user = userEvent.setup();
      const handleClear = vi.fn();
      render(<BatchActionBar count={1} actions={[]} onClear={handleClear} />);
      await user.click(screen.getByRole("button", { name: "Clear" }));
      expect(handleClear).toHaveBeenCalledOnce();
    });

    it("calls each action's onClick independently", async () => {
      const user = userEvent.setup();
      const handleEdit = vi.fn();
      const handleDelete = vi.fn();
      const actions = [
        { label: "Edit", onClick: handleEdit },
        { label: "Delete", onClick: handleDelete, variant: "danger" as const },
      ];
      render(<BatchActionBar count={2} actions={actions} onClear={vi.fn()} />);
      await user.click(screen.getByRole("button", { name: "Edit" }));
      expect(handleEdit).toHaveBeenCalledOnce();
      expect(handleDelete).not.toHaveBeenCalled();

      await user.click(screen.getByRole("button", { name: "Delete" }));
      expect(handleDelete).toHaveBeenCalledOnce();
    });
  });

  describe("conditional rendering on count change", () => {
    it("renders when count transitions from 0 to positive", () => {
      const { rerender } = render(<BatchActionBar count={0} actions={[]} onClear={vi.fn()} />);
      expect(screen.queryByText(/selected/)).not.toBeInTheDocument();

      rerender(<BatchActionBar count={5} actions={[]} onClear={vi.fn()} />);
      expect(screen.getByText("5 selected")).toBeInTheDocument();
    });

    it("hides the bar when count goes back to 0", () => {
      const { rerender } = render(<BatchActionBar count={3} actions={[]} onClear={vi.fn()} />);
      expect(screen.getByText("3 selected")).toBeInTheDocument();

      rerender(<BatchActionBar count={0} actions={[]} onClear={vi.fn()} />);
      expect(screen.queryByText(/selected/)).not.toBeInTheDocument();
    });
  });
});
