/**
 * ConnectionCard 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 { ConnectionCard } from "./ConnectionCard";
import { FederationConnectionStatus, type ConnectionDetails } from "@/lib/api/federation";

describe("ConnectionCard", (): void => {
  const mockActiveConnection: ConnectionDetails = {
    id: "conn-1",
    workspaceId: "workspace-1",
    remoteInstanceId: "instance-work-001",
    remoteUrl: "https://mosaic.work.example.com",
    remotePublicKey: "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----",
    remoteCapabilities: {
      supportsQuery: true,
      supportsCommand: true,
      supportsEvent: true,
      supportsAgentSpawn: true,
      protocolVersion: "1.0",
    },
    status: FederationConnectionStatus.ACTIVE,
    metadata: {
      name: "Work Instance",
      description: "Corporate Mosaic instance",
    },
    createdAt: new Date("2026-02-01").toISOString(),
    updatedAt: new Date("2026-02-01").toISOString(),
    connectedAt: new Date("2026-02-01").toISOString(),
    disconnectedAt: null,
  };

  const mockPendingConnection: ConnectionDetails = {
    ...mockActiveConnection,
    id: "conn-2",
    status: FederationConnectionStatus.PENDING,
    metadata: {
      name: "Partner Instance",
      description: "Awaiting acceptance",
    },
    connectedAt: null,
  };

  const mockOnAccept = vi.fn();
  const mockOnReject = vi.fn();
  const mockOnDisconnect = vi.fn();

  it("should render connection name from metadata", (): void => {
    render(<ConnectionCard connection={mockActiveConnection} />);
    expect(screen.getByText("Work Instance")).toBeInTheDocument();
  });

  it("should render connection URL", (): void => {
    render(<ConnectionCard connection={mockActiveConnection} />);
    expect(screen.getByText("https://mosaic.work.example.com")).toBeInTheDocument();
  });

  it("should render connection description from metadata", (): void => {
    render(<ConnectionCard connection={mockActiveConnection} />);
    expect(screen.getByText("Corporate Mosaic instance")).toBeInTheDocument();
  });

  it("should show Active status with green indicator for active connections", (): void => {
    render(<ConnectionCard connection={mockActiveConnection} />);
    expect(screen.getByText("Active")).toBeInTheDocument();
  });

  it("should show Pending status with blue indicator for pending connections", (): void => {
    render(<ConnectionCard connection={mockPendingConnection} />);
    expect(screen.getByText("Pending")).toBeInTheDocument();
  });

  it("should show Disconnected status for disconnected connections", (): void => {
    const disconnectedConnection = {
      ...mockActiveConnection,
      status: FederationConnectionStatus.DISCONNECTED,
      disconnectedAt: new Date("2026-02-02").toISOString(),
    };
    render(<ConnectionCard connection={disconnectedConnection} />);
    expect(screen.getByText("Disconnected")).toBeInTheDocument();
  });

  it("should show Rejected status for rejected connections", (): void => {
    const rejectedConnection = {
      ...mockActiveConnection,
      status: FederationConnectionStatus.REJECTED,
    };
    render(<ConnectionCard connection={rejectedConnection} />);
    expect(screen.getByText("Rejected")).toBeInTheDocument();
  });

  it("should show Disconnect button for active connections", (): void => {
    render(<ConnectionCard connection={mockActiveConnection} onDisconnect={mockOnDisconnect} />);
    expect(screen.getByRole("button", { name: /disconnect/i })).toBeInTheDocument();
  });

  it("should show Accept and Reject buttons for pending connections", (): void => {
    render(
      <ConnectionCard
        connection={mockPendingConnection}
        onAccept={mockOnAccept}
        onReject={mockOnReject}
      />
    );
    expect(screen.getByRole("button", { name: /accept/i })).toBeInTheDocument();
    expect(screen.getByRole("button", { name: /reject/i })).toBeInTheDocument();
  });

  it("should not show action buttons for disconnected connections", (): void => {
    const disconnectedConnection = {
      ...mockActiveConnection,
      status: FederationConnectionStatus.DISCONNECTED,
    };
    render(<ConnectionCard connection={disconnectedConnection} />);
    expect(screen.queryByRole("button")).not.toBeInTheDocument();
  });

  it("should call onAccept when accept button clicked", async (): Promise<void> => {
    const user = userEvent.setup();
    render(
      <ConnectionCard
        connection={mockPendingConnection}
        onAccept={mockOnAccept}
        onReject={mockOnReject}
      />
    );

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

    expect(mockOnAccept).toHaveBeenCalledWith(mockPendingConnection.id);
  });

  it("should call onReject when reject button clicked", async (): Promise<void> => {
    const user = userEvent.setup();
    render(
      <ConnectionCard
        connection={mockPendingConnection}
        onAccept={mockOnAccept}
        onReject={mockOnReject}
      />
    );

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

    expect(mockOnReject).toHaveBeenCalledWith(mockPendingConnection.id);
  });

  it("should call onDisconnect when disconnect button clicked", async (): Promise<void> => {
    const user = userEvent.setup();
    render(<ConnectionCard connection={mockActiveConnection} onDisconnect={mockOnDisconnect} />);

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

    expect(mockOnDisconnect).toHaveBeenCalledWith(mockActiveConnection.id);
  });

  it("should display capabilities when showDetails is true", (): void => {
    render(<ConnectionCard connection={mockActiveConnection} showDetails={true} />);
    expect(screen.getByText(/Query/i)).toBeInTheDocument();
    expect(screen.getByText(/Command/i)).toBeInTheDocument();
    expect(screen.getByText(/Events/i)).toBeInTheDocument();
    expect(screen.getByText(/Agent Spawn/i)).toBeInTheDocument();
  });

  it("should not display capabilities by default", (): void => {
    render(<ConnectionCard connection={mockActiveConnection} />);
    // Capabilities should not be visible without showDetails=true
    const card = screen.getByText("Work Instance").closest("div");
    expect(card?.textContent).not.toMatch(/Query.*Command.*Events/);
  });

  it("should use fallback name if metadata name is missing", (): void => {
    const connectionWithoutName = {
      ...mockActiveConnection,
      metadata: {},
    };
    render(<ConnectionCard connection={connectionWithoutName} />);
    expect(screen.getByText("Remote Instance")).toBeInTheDocument();
  });

  it("should render with compact layout when compact prop is true", (): void => {
    const { container } = render(
      <ConnectionCard connection={mockActiveConnection} compact={true} />
    );
    // Verify compact class is applied
    expect(container.querySelector(".p-3")).toBeInTheDocument();
  });

  it("should render with full layout by default", (): void => {
    const { container } = render(<ConnectionCard connection={mockActiveConnection} />);
    // Verify full padding is applied
    expect(container.querySelector(".p-4")).toBeInTheDocument();
  });
});
