/**
 * BaseWidget Component Tests
 * Following TDD - write tests first!
 */

import { describe, it, expect, vi } from "vitest";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { BaseWidget } from "../BaseWidget";

describe("BaseWidget", (): void => {
  const mockOnEdit = vi.fn();
  const mockOnRemove = vi.fn();

  it("should render children content", (): void => {
    render(
      <BaseWidget id="test-widget" title="Test Widget" onEdit={mockOnEdit} onRemove={mockOnRemove}>
        <div>Widget Content</div>
      </BaseWidget>
    );

    expect(screen.getByText("Widget Content")).toBeInTheDocument();
  });

  it("should render title", (): void => {
    render(
      <BaseWidget
        id="test-widget"
        title="My Custom Widget"
        onEdit={mockOnEdit}
        onRemove={mockOnRemove}
      >
        <div>Content</div>
      </BaseWidget>
    );

    expect(screen.getByText("My Custom Widget")).toBeInTheDocument();
  });

  it("should call onEdit when edit button clicked", async (): Promise<void> => {
    const user = userEvent.setup();
    render(
      <BaseWidget id="test-widget" title="Test Widget" onEdit={mockOnEdit} onRemove={mockOnRemove}>
        <div>Content</div>
      </BaseWidget>
    );

    const editButton = screen.getByRole("button", { name: /edit/i });
    await user.click(editButton);

    expect(mockOnEdit).toHaveBeenCalledTimes(1);
  });

  it("should call onRemove when remove button clicked", async (): Promise<void> => {
    const user = userEvent.setup();
    render(
      <BaseWidget id="test-widget" title="Test Widget" onEdit={mockOnEdit} onRemove={mockOnRemove}>
        <div>Content</div>
      </BaseWidget>
    );

    const removeButton = screen.getByRole("button", { name: /remove/i });
    await user.click(removeButton);

    expect(mockOnRemove).toHaveBeenCalledTimes(1);
  });

  it("should not show control buttons when handlers not provided", (): void => {
    render(
      <BaseWidget id="test-widget" title="Test Widget">
        <div>Content</div>
      </BaseWidget>
    );

    expect(screen.queryByRole("button", { name: /edit/i })).not.toBeInTheDocument();
    expect(screen.queryByRole("button", { name: /remove/i })).not.toBeInTheDocument();
  });

  it("should render with description when provided", (): void => {
    render(
      <BaseWidget id="test-widget" title="Test Widget" description="This is a test description">
        <div>Content</div>
      </BaseWidget>
    );

    expect(screen.getByText("This is a test description")).toBeInTheDocument();
  });

  it("should apply custom className", (): void => {
    const { container } = render(
      <BaseWidget id="test-widget" title="Test Widget" className="custom-class">
        <div>Content</div>
      </BaseWidget>
    );

    expect(container.querySelector(".custom-class")).toBeInTheDocument();
  });

  it("should render loading state", (): void => {
    render(
      <BaseWidget id="test-widget" title="Test Widget" isLoading={true}>
        <div>Content</div>
      </BaseWidget>
    );

    expect(screen.getByText(/loading/i)).toBeInTheDocument();
  });

  it("should render error state", (): void => {
    render(
      <BaseWidget id="test-widget" title="Test Widget" error="Something went wrong">
        <div>Content</div>
      </BaseWidget>
    );

    expect(screen.getByText("Something went wrong")).toBeInTheDocument();
  });
});
