import { describe, it, expect, vi, beforeEach } from "vitest";
import { render, screen, waitFor } from "@testing-library/react";
import { FluentProvider, webLightTheme } from "@fluentui/react-components";
import { ServerHealthSection } from "../ServerHealthSection";

vi.mock("../../../api/config");

import { fetchFail2BanLog, fetchServiceStatus } from "../../../api/config";

const mockedFetchServiceStatus = vi.mocked(fetchServiceStatus);
const mockedFetchFail2BanLog = vi.mocked(fetchFail2BanLog);

describe("ServerHealthSection", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("shows the version in the service health panel", async () => {
    mockedFetchServiceStatus.mockResolvedValue({
      online: true,
      version: "1.2.3",
      jail_count: 2,
      total_bans: 5,
      total_failures: 1,
      log_level: "INFO",
      log_target: "STDOUT",
    });

    mockedFetchFail2BanLog.mockResolvedValue({
      log_path: "/var/log/fail2ban.log",
      lines: ["2026-01-01 fail2ban[123]: INFO  Test"],
      total_lines: 1,
      log_level: "INFO",
      log_target: "STDOUT",
    });

    render(
      <FluentProvider theme={webLightTheme}>
        <ServerHealthSection />
      </FluentProvider>,
    );

    // The service health panel should render and include the version.
    const versionLabel = await screen.findByText("Version");
    expect(versionLabel).toBeInTheDocument();

    const versionCard = versionLabel.closest("div");
    expect(versionCard).toHaveTextContent("1.2.3");
  });

  it("renders the toolbar with filter and lines count controls when log data is available", async () => {
    mockedFetchServiceStatus.mockResolvedValue({
      online: true,
      version: "1.2.3",
      jail_count: 2,
      total_bans: 5,
      total_failures: 1,
      log_level: "INFO",
      log_target: "/var/log/fail2ban.log",
    });

    mockedFetchFail2BanLog.mockResolvedValue({
      log_path: "/var/log/fail2ban.log",
      lines: ["2026-01-01 fail2ban[123]: INFO  Test line"],
      total_lines: 1,
      log_level: "INFO",
      log_target: "/var/log/fail2ban.log",
    });

    render(
      <FluentProvider theme={webLightTheme}>
        <ServerHealthSection />
      </FluentProvider>,
    );

    // Wait for toolbar controls to appear
    const filterInput = await screen.findByPlaceholderText("Substring filter…");
    expect(filterInput).toBeInTheDocument();

    // The refresh button should be visible
    const refreshButton = screen.getByRole("button", { name: /Refresh/i });
    expect(refreshButton).toBeInTheDocument();
  });

  it("displays log lines with appropriate styling", async () => {
    mockedFetchServiceStatus.mockResolvedValue({
      online: true,
      version: "1.2.3",
      jail_count: 2,
      total_bans: 5,
      total_failures: 1,
      log_level: "INFO",
      log_target: "/var/log/fail2ban.log",
    });

    mockedFetchFail2BanLog.mockResolvedValue({
      log_path: "/var/log/fail2ban.log",
      lines: [
        "2026-01-01 fail2ban[123]: INFO  Normal info message",
        "2026-01-01 fail2ban[124]: WARNING Something is wrong",
        "2026-01-01 fail2ban[125]: ERROR Critical failure",
      ],
      total_lines: 3,
      log_level: "INFO",
      log_target: "/var/log/fail2ban.log",
    });

    render(
      <FluentProvider theme={webLightTheme}>
        <ServerHealthSection />
      </FluentProvider>,
    );

    // Wait for log lines to appear
    await waitFor(() => {
      expect(screen.getByText(/Normal info message/)).toBeInTheDocument();
    });

    expect(screen.getByText(/Something is wrong/)).toBeInTheDocument();
    expect(screen.getByText(/Critical failure/)).toBeInTheDocument();
  });

  it("calls fetchFail2BanLog with the correct initial linesCount", async () => {
    mockedFetchServiceStatus.mockResolvedValue({
      online: true,
      version: "1.2.3",
      jail_count: 2,
      total_bans: 5,
      total_failures: 1,
      log_level: "INFO",
      log_target: "/var/log/fail2ban.log",
    });

    mockedFetchFail2BanLog.mockResolvedValue({
      log_path: "/var/log/fail2ban.log",
      lines: [],
      total_lines: 0,
      log_level: "INFO",
      log_target: "/var/log/fail2ban.log",
    });

    render(
      <FluentProvider theme={webLightTheme}>
        <ServerHealthSection />
      </FluentProvider>,
    );

    // Wait for the initial API call
    await waitFor(() => {
      expect(mockedFetchFail2BanLog).toHaveBeenCalled();
    });

    // Should be called with default 200 lines
    const calls = mockedFetchFail2BanLog.mock.calls;
    expect(calls.length).toBeGreaterThan(0);
    expect(calls[0]?.[0]).toBe(200);
  });
});
