import { render, screen, fireEvent } from "@testing-library/react";
import { expect, test, vi } from "vitest";
import { LicenseTab } from "./LicenseTab";

test("renders licensed status when licensed", () => {
  render(
    <LicenseTab
      isLicensed={true}
      hwid="hw-123"
      keyInput=""
      isActivating={false}
      error=""
      onKeyInputChange={() => {}}
      onActivate={() => {}}
      onOfflineActivate={() => {}}
    />,
  );

  expect(screen.getByText("Active")).toBeInTheDocument();
  expect(
    screen.queryByRole("button", { name: /activate/i }),
  ).not.toBeInTheDocument();
  expect(screen.getByText("hw-123")).toBeInTheDocument();
});

test("renders activation form when unlicensed", () => {
  const onKeyInputChange = vi.fn();
  const onActivate = vi.fn();

  render(
    <LicenseTab
      isLicensed={false}
      hwid="hw-123"
      keyInput="my-key"
      isActivating={false}
      error="Invalid key"
      onKeyInputChange={onKeyInputChange}
      onActivate={onActivate}
      onOfflineActivate={() => {}}
    />,
  );

  expect(screen.getByText("Unregistered")).toBeInTheDocument();

  const input = screen.getByPlaceholderText(/enter license key.../i);

  expect(input).toHaveValue("my-key");

  fireEvent.change(input, { target: { value: "new-key" } });

  expect(onKeyInputChange).toHaveBeenCalledWith("new-key");

  expect(screen.getByText("Invalid key")).toBeInTheDocument();

  const button = screen.getByRole("button", { name: "Activate" });

  fireEvent.click(button);

  expect(onActivate).toHaveBeenCalledTimes(1);
});

test("renders spinner and disables input when activating", () => {
  render(
    <LicenseTab
      isLicensed={false}
      hwid="hw-123"
      keyInput="my-key"
      isActivating={true}
      error=""
      onKeyInputChange={() => {}}
      onActivate={() => {}}
      onOfflineActivate={() => {}}
    />,
  );

  expect(screen.getByPlaceholderText(/enter license key.../i)).toBeDisabled();
  expect(screen.getByRole("button", { name: /activating/i })).toBeDisabled();
  expect(screen.getByText("Activating...")).toBeInTheDocument();
});

test("switches to offline mode when toggle clicked", () => {
  render(
    <LicenseTab
      isLicensed={false}
      hwid="hw-123"
      keyInput=""
      isActivating={false}
      error=""
      onKeyInputChange={() => {}}
      onActivate={() => {}}
      onOfflineActivate={() => {}}
    />,
  );

  const toggle = screen.getByText("Have an offline token?");

  fireEvent.click(toggle);

  expect(
    screen.getByPlaceholderText(/paste offline token/i),
  ).toBeInTheDocument();
  expect(
    screen.queryByPlaceholderText(/enter license key.../i),
  ).not.toBeInTheDocument();
});

test("calls onOfflineActivate with token when offline mode submitted", () => {
  const onOfflineActivate = vi.fn();

  render(
    <LicenseTab
      isLicensed={false}
      hwid="hw-123"
      keyInput=""
      isActivating={false}
      error=""
      onKeyInputChange={() => {}}
      onActivate={() => {}}
      onOfflineActivate={onOfflineActivate}
    />,
  );

  fireEvent.click(screen.getByText("Have an offline token?"));

  const input = screen.getByPlaceholderText(/paste offline token/i);

  fireEvent.change(input, { target: { value: "test.payload.signature" } });
  fireEvent.click(screen.getByRole("button", { name: "Verify Token" }));

  expect(onOfflineActivate).toHaveBeenCalledWith("test.payload.signature");
});

test("switches back to online mode from offline mode", () => {
  render(
    <LicenseTab
      isLicensed={false}
      hwid="hw-123"
      keyInput=""
      isActivating={false}
      error=""
      onKeyInputChange={() => {}}
      onActivate={() => {}}
      onOfflineActivate={() => {}}
    />,
  );

  fireEvent.click(screen.getByText("Have an offline token?"));
  expect(
    screen.getByPlaceholderText(/paste offline token/i),
  ).toBeInTheDocument();

  fireEvent.click(screen.getByText("Activate with license key instead"));
  expect(
    screen.getByPlaceholderText(/enter license key.../i),
  ).toBeInTheDocument();
  expect(
    screen.queryByPlaceholderText(/paste offline token/i),
  ).not.toBeInTheDocument();
});
