// @vitest-environment jsdom

import { render, screen, fireEvent, cleanup } from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vitest";
import { DiagramSourcePanel } from "./DiagramSourcePanel";

// Tell React this environment uses act() for event flushing.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(globalThis as any).IS_REACT_ACT_ENVIRONMENT = true;

afterEach(() => {
  cleanup();
  vi.clearAllMocks();
});

describe("DiagramSourcePanel", () => {
  const defaultSource = "graph TD\n  A --> B";

  it("shows 'View Mermaid source' trigger in collapsed state", () => {
    render(<DiagramSourcePanel mermaidSource={defaultSource} onRerender={vi.fn()} />);
    expect(screen.getByText("View Mermaid source")).toBeTruthy();
  });

  it("clicking trigger expands to show textarea with mermaidSource", () => {
    render(<DiagramSourcePanel mermaidSource={defaultSource} onRerender={vi.fn()} />);
    const trigger = screen.getByText("View Mermaid source");
    fireEvent.click(trigger);
    const textarea = screen.getByRole("textbox") as HTMLTextAreaElement;
    expect(textarea).toBeTruthy();
    expect(textarea.value).toBe(defaultSource);
  });

  it("expanded state shows 'Hide source' trigger text", () => {
    render(<DiagramSourcePanel mermaidSource={defaultSource} onRerender={vi.fn()} />);
    const trigger = screen.getByText("View Mermaid source");
    fireEvent.click(trigger);
    expect(screen.getByText("Hide source")).toBeTruthy();
  });

  it("'Copy source' button has aria-label='Copy source'", () => {
    render(<DiagramSourcePanel mermaidSource={defaultSource} onRerender={vi.fn()} />);
    const trigger = screen.getByText("View Mermaid source");
    fireEvent.click(trigger);
    const copyBtn = screen.getByRole("button", { name: "Copy source" });
    expect(copyBtn).toBeTruthy();
    expect(copyBtn.getAttribute("aria-label")).toBe("Copy source");
  });

  it("editing textarea and blurring shows 'Re-render diagram' button", () => {
    render(<DiagramSourcePanel mermaidSource={defaultSource} onRerender={vi.fn()} />);
    const trigger = screen.getByText("View Mermaid source");
    fireEvent.click(trigger);
    const textarea = screen.getByRole("textbox") as HTMLTextAreaElement;
    fireEvent.change(textarea, { target: { value: "graph LR\n  X --> Y" } });
    fireEvent.blur(textarea);
    expect(screen.getByText("Re-render diagram")).toBeTruthy();
  });

  it("clicking 'Re-render diagram' calls onRerender with edited source", () => {
    const onRerender = vi.fn();
    render(<DiagramSourcePanel mermaidSource={defaultSource} onRerender={onRerender} />);
    const trigger = screen.getByText("View Mermaid source");
    fireEvent.click(trigger);
    const textarea = screen.getByRole("textbox") as HTMLTextAreaElement;
    const editedSource = "graph LR\n  X --> Y";
    fireEvent.change(textarea, { target: { value: editedSource } });
    fireEvent.blur(textarea);
    const rerenderBtn = screen.getByText("Re-render diagram");
    fireEvent.click(rerenderBtn);
    expect(onRerender).toHaveBeenCalledWith(editedSource);
  });
});
