import { describe, it, expect, vi } from "vitest";
import { render, screen } from "@testing-library/react";
import { FluentProvider, webLightTheme } from "@fluentui/react-components";
import { ActionForm } from "../ActionForm";
import type { ActionConfig } from "../../../types/config";

// Mock the useActionConfig hook so tests don't make real API calls.
vi.mock("../../../hooks/useActionConfig");

import { useActionConfig } from "../../../hooks/useActionConfig";

const mockUseActionConfig = vi.mocked(useActionConfig);

const mockConfig: ActionConfig = {
  name: "iptables",
  filename: "iptables.conf",
  before: null,
  after: null,
  actionstart: "iptables -N fail2ban-<name>",
  actionstop: "iptables -F fail2ban-<name>",
  actioncheck: null,
  actionban: "iptables -I INPUT -s <ip> -j DROP",
  actionunban: "iptables -D INPUT -s <ip> -j DROP",
  actionflush: null,
  definition_vars: {},
  init_vars: {},
  active: false,
  used_by_jails: [],
  source_file: "iptables.conf",
  has_local_override: false,
};

function renderForm(name: string) {
  return render(
    <FluentProvider theme={webLightTheme}>
      <ActionForm name={name} />
    </FluentProvider>,
  );
}

describe("ActionForm", () => {
  it("shows skeleton while loading", () => {
    mockUseActionConfig.mockReturnValue({
      config: null,
      loading: true,
      error: null,
      saving: false,
      saveError: null,
      refresh: vi.fn(),
      save: vi.fn(),
    });

    renderForm("iptables");
    expect(screen.getByLabelText(/loading iptables/i)).toBeInTheDocument();
  });

  it("shows error message when loading fails", () => {
    mockUseActionConfig.mockReturnValue({
      config: null,
      loading: false,
      error: "Timeout",
      saving: false,
      saveError: null,
      refresh: vi.fn(),
      save: vi.fn(),
    });

    renderForm("iptables");
    expect(screen.getByText(/timeout/i)).toBeInTheDocument();
  });

  it("shows fallback error when config is null with no error message", () => {
    mockUseActionConfig.mockReturnValue({
      config: null,
      loading: false,
      error: null,
      saving: false,
      saveError: null,
      refresh: vi.fn(),
      save: vi.fn(),
    });

    renderForm("iptables");
    expect(screen.getByText(/failed to load action config/i)).toBeInTheDocument();
  });

  it("renders form accordion sections when config is loaded", () => {
    mockUseActionConfig.mockReturnValue({
      config: mockConfig,
      loading: false,
      error: null,
      saving: false,
      saveError: null,
      refresh: vi.fn(),
      save: vi.fn(),
    });

    renderForm("iptables");
    expect(screen.getByText(/includes/i)).toBeInTheDocument();
    expect(screen.getByText(/definition/i)).toBeInTheDocument();
  });

  it("passes the action name to useActionConfig", () => {
    mockUseActionConfig.mockReturnValue({
      config: null,
      loading: true,
      error: null,
      saving: false,
      saveError: null,
      refresh: vi.fn(),
      save: vi.fn(),
    });

    renderForm("iptables-multiport");
    expect(mockUseActionConfig).toHaveBeenCalledWith("iptables-multiport");
  });
});
