/**
 * Tests for SpokeConfigurationForm Component
 */

import { describe, it, expect, vi } from "vitest";
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import { SpokeConfigurationForm } from "./SpokeConfigurationForm";
import type { PublicInstanceIdentity } from "@/lib/api/federation";

describe("SpokeConfigurationForm", () => {
  const mockInstance: PublicInstanceIdentity = {
    id: "instance-123",
    instanceId: "test-instance-001",
    name: "Test Instance",
    url: "https://test.example.com",
    publicKey: "-----BEGIN PUBLIC KEY-----\nMOCKPUBLICKEY\n-----END PUBLIC KEY-----",
    capabilities: {
      supportsQuery: true,
      supportsCommand: true,
      supportsEvent: true,
      supportsAgentSpawn: false,
      protocolVersion: "1.0",
    },
    metadata: {
      description: "Test instance description",
    },
    createdAt: "2026-02-01T00:00:00Z",
    updatedAt: "2026-02-01T00:00:00Z",
  };

  it("should render instance identity information", () => {
    const onSave = vi.fn();
    render(<SpokeConfigurationForm instance={mockInstance} onSave={onSave} />);

    expect(screen.getByDisplayValue("Test Instance")).toBeInTheDocument();
    expect(screen.getByText("test-instance-001")).toBeInTheDocument();
    expect(screen.getByText("https://test.example.com")).toBeInTheDocument();
  });

  it("should render capability toggles with correct initial state", () => {
    const onSave = vi.fn();
    render(<SpokeConfigurationForm instance={mockInstance} onSave={onSave} />);

    const queryToggle = screen.getByLabelText(/Query Support/i);
    const commandToggle = screen.getByLabelText(/Command Support/i);
    const eventToggle = screen.getByLabelText(/Event Support/i);
    const agentToggle = screen.getByLabelText(/Agent Spawn Support/i);

    expect(queryToggle).toBeChecked();
    expect(commandToggle).toBeChecked();
    expect(eventToggle).toBeChecked();
    expect(agentToggle).not.toBeChecked();
  });

  it("should allow editing instance name", async () => {
    const onSave = vi.fn();
    render(<SpokeConfigurationForm instance={mockInstance} onSave={onSave} />);

    const nameInput = screen.getByDisplayValue("Test Instance");
    fireEvent.change(nameInput, { target: { value: "Updated Instance" } });

    await waitFor(() => {
      expect(screen.getByDisplayValue("Updated Instance")).toBeInTheDocument();
    });
  });

  it("should toggle capabilities", async () => {
    const onSave = vi.fn();
    render(<SpokeConfigurationForm instance={mockInstance} onSave={onSave} />);

    const agentToggle = screen.getByLabelText(/Agent Spawn Support/i);
    expect(agentToggle).not.toBeChecked();

    fireEvent.click(agentToggle);

    await waitFor(() => {
      expect(agentToggle).toBeChecked();
    });
  });

  it("should call onSave with updated configuration", async () => {
    const onSave = vi.fn();
    render(<SpokeConfigurationForm instance={mockInstance} onSave={onSave} />);

    // Change name
    const nameInput = screen.getByDisplayValue("Test Instance");
    fireEvent.change(nameInput, { target: { value: "Updated Instance" } });

    // Toggle agent spawn
    const agentToggle = screen.getByLabelText(/Agent Spawn Support/i);
    fireEvent.click(agentToggle);

    // Click save
    const saveButton = screen.getByText("Save Configuration");
    fireEvent.click(saveButton);

    await waitFor(() => {
      expect(onSave).toHaveBeenCalledWith({
        name: "Updated Instance",
        capabilities: {
          supportsQuery: true,
          supportsCommand: true,
          supportsEvent: true,
          supportsAgentSpawn: true,
          protocolVersion: "1.0",
        },
        metadata: {
          description: "Test instance description",
        },
      });
    });
  });

  it("should display loading state when saving", () => {
    const onSave = vi.fn();
    render(<SpokeConfigurationForm instance={mockInstance} onSave={onSave} isLoading={true} />);

    const saveButton = screen.getByText("Saving...");
    expect(saveButton).toBeDisabled();
  });

  it("should display error message when provided", () => {
    const onSave = vi.fn();
    render(
      <SpokeConfigurationForm
        instance={mockInstance}
        onSave={onSave}
        error="Unable to save configuration"
      />
    );

    expect(screen.getByText("Unable to save configuration")).toBeInTheDocument();
  });

  it("should use PDA-friendly language in help text", () => {
    const onSave = vi.fn();
    render(<SpokeConfigurationForm instance={mockInstance} onSave={onSave} />);

    // Should NOT use demanding language
    expect(screen.queryByText(/must/i)).not.toBeInTheDocument();
    expect(screen.queryByText(/required/i)).not.toBeInTheDocument();
    expect(screen.queryByText(/critical/i)).not.toBeInTheDocument();

    // Should use friendly language (multiple instances expected)
    const friendlyText = screen.getAllByText(/Allows connected instances/i);
    expect(friendlyText.length).toBeGreaterThan(0);
  });

  it("should truncate public key and show copy button", () => {
    const onSave = vi.fn();
    render(<SpokeConfigurationForm instance={mockInstance} onSave={onSave} />);

    // Public key should be truncated
    expect(screen.getByText(/-----BEGIN PUBLIC KEY-----/)).toBeInTheDocument();
    expect(screen.getByText(/Copy/i)).toBeInTheDocument();
  });

  it("should handle cancel action", async () => {
    const onSave = vi.fn();
    const onCancel = vi.fn();
    render(<SpokeConfigurationForm instance={mockInstance} onSave={onSave} onCancel={onCancel} />);

    const cancelButton = screen.getByText("Cancel");
    fireEvent.click(cancelButton);

    await waitFor(() => {
      expect(onCancel).toHaveBeenCalled();
    });
  });
});
