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

// Component that throws an error for testing
function ThrowError({ shouldThrow }: { shouldThrow: boolean }) {
  if (shouldThrow) {
    throw new Error("Test error");
  }
  return <div>No error</div>;
}

describe("ErrorBoundary", () => {
  // Suppress console.error for these tests
  const originalError = console.error;
  beforeEach(() => {
    console.error = vi.fn();
  });
  afterEach(() => {
    console.error = originalError;
  });

  it("should render children when there is no error", () => {
    render(
      <ErrorBoundary>
        <div>Test content</div>
      </ErrorBoundary>
    );

    expect(screen.getByText("Test content")).toBeInTheDocument();
  });

  it("should render error UI when child throws error", () => {
    render(
      <ErrorBoundary>
        <ThrowError shouldThrow={true} />
      </ErrorBoundary>
    );

    // Should show PDA-friendly message, not harsh "error" language
    expect(screen.getByText(/something unexpected happened/i)).toBeInTheDocument();
  });

  it("should use PDA-friendly language without demanding words", () => {
    render(
      <ErrorBoundary>
        <ThrowError shouldThrow={true} />
      </ErrorBoundary>
    );

    const errorText = screen.getByText(/something unexpected happened/i).textContent || "";

    // Should NOT contain demanding/harsh words
    expect(errorText.toLowerCase()).not.toMatch(/error|critical|urgent|must|required/);
  });

  it("should provide a reload option", () => {
    render(
      <ErrorBoundary>
        <ThrowError shouldThrow={true} />
      </ErrorBoundary>
    );

    const reloadButton = screen.getByRole("button", { name: /refresh/i });
    expect(reloadButton).toBeInTheDocument();
  });

  it("should reload page when reload button is clicked", async () => {
    const user = userEvent.setup();
    const mockReload = vi.fn();
    Object.defineProperty(window, "location", {
      value: { reload: mockReload },
      writable: true,
    });

    render(
      <ErrorBoundary>
        <ThrowError shouldThrow={true} />
      </ErrorBoundary>
    );

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

    expect(mockReload).toHaveBeenCalled();
  });

  it("should provide a way to go back home", () => {
    render(
      <ErrorBoundary>
        <ThrowError shouldThrow={true} />
      </ErrorBoundary>
    );

    const homeLink = screen.getByRole("link", { name: /home/i });
    expect(homeLink).toBeInTheDocument();
    expect(homeLink).toHaveAttribute("href", "/");
  });

  it("should have calm, non-alarming visual design", () => {
    render(
      <ErrorBoundary>
        <ThrowError shouldThrow={true} />
      </ErrorBoundary>
    );

    const container = screen.getByText(/something unexpected happened/i).closest("div");

    // Should not have aggressive red colors (check for calm colors)
    const className = container?.className || "";
    expect(className).not.toMatch(/bg-red-|text-red-/);
  });
});
