import type { ReactNode } from "react";
import { renderToStaticMarkup } from "react-dom/server";
import { describe, expect, it } from "vitest";
import { getMessages } from "@/i18n/messages";
import { I18nProvider } from "@/i18n/provider";
import { AdvancedSettingsEditor } from "./advanced-settings-editor";
import { createInitialCapacities } from "./issuance-draft-wizard.types";

function renderWithI18n(children: ReactNode) {
  return renderToStaticMarkup(
    <I18nProvider locale="en" messages={getMessages("en")}>
      {children}
    </I18nProvider>
  );
}

const baseProps = {
  category: "stablecoin" as const,
  type: "fiat_backed",
  settings: {},
  onSettingsChange: () => undefined,
  capacities: createInitialCapacities(),
  onCapacitiesChange: () => undefined,
};

describe("AdvancedSettingsEditor", () => {
  it("renders one collapsed list with permanent and ongoing sections (no mode tabs)", () => {
    const markup = renderWithI18n(<AdvancedSettingsEditor {...baseProps} />);
    expect(markup).toContain("Permanent");
    expect(markup).toContain("Ongoing");
    // The Basic/Detailed/Expert tabs are gone.
    expect(markup).not.toContain("Detailed");
    expect(markup).not.toContain("Expert");
  });

  it("keeps setting labels human and hides technical extension names until toggled", () => {
    const markup = renderWithI18n(<AdvancedSettingsEditor {...baseProps} />);
    expect(markup).toContain(">View<");
    // stablecoin locks the pausable extension; its raw name only shows in technical mode.
    expect(markup).not.toContain("pausable");
  });

  it("renders the access-control row only when a change handler is provided", () => {
    const withAccess = renderWithI18n(
      <AdvancedSettingsEditor
        {...baseProps}
        accessControl=""
        onAccessControlChange={() => undefined}
      />
    );
    expect(withAccess).toContain("Access control");
    expect(withAccess).toContain("Allow list");
    // The single-select control is backed by native radio inputs, not tab-role
    // buttons (there are no tabpanels behind it) — a screen-reader correctness guard.
    expect(withAccess).toContain('type="radio"');
    expect(withAccess).not.toContain('role="tablist"');
    expect(withAccess).not.toContain('role="tab"');

    const withoutAccess = renderWithI18n(<AdvancedSettingsEditor {...baseProps} />);
    expect(withoutAccess).not.toContain("Access control");
  });

  it("renders off-chain capacities as plain toggles (no not-enforced badge)", () => {
    const markup = renderWithI18n(<AdvancedSettingsEditor {...baseProps} />);
    expect(markup).toContain("Verified holders"); // the kyc capacity label
    expect(markup).not.toContain("Not enforced yet");
  });

  it("uses jargon-free capacity descriptions in the default (non-technical) view", () => {
    const markup = renderWithI18n(<AdvancedSettingsEditor {...baseProps} />);
    // Institutional wording is shown by default...
    expect(markup).toContain("issue new units or retire existing ones");
    // ...the token/mint/burn phrasing is reserved for the technical view.
    expect(markup).not.toContain("mint new tokens or burn existing supply");
  });

  it("reveals a Configure affordance for a configurable capacity when config is allowed", () => {
    const capacities = createInitialCapacities();
    capacities.restrictTradingHours = { enabled: true };
    const markup = renderWithI18n(
      <AdvancedSettingsEditor {...baseProps} capacities={capacities} allowCapacityConfig />
    );
    expect(markup).toContain("Configure");
    expect(markup).toContain("Not configured yet");
  });

  it("keeps capacities declaration-only in the wizard: no per-card config UI", () => {
    const capacities = createInitialCapacities();
    capacities.restrictTradingHours = { enabled: true };
    const markup = renderWithI18n(
      <AdvancedSettingsEditor {...baseProps} capacities={capacities} />
    );
    // No per-card Configure / summary in the wizard...
    expect(markup).not.toContain("Not configured yet");
    // ...the section subtitle explains config happens later on the compliance tab.
    expect(markup).toContain("configured later on the compliance tab");
  });

  it("offers quick-fill presets, hidden once the on-chain settings are read-only", () => {
    const editable = renderWithI18n(<AdvancedSettingsEditor {...baseProps} />);
    expect(editable).toContain("Start from a scenario");

    const readOnly = renderWithI18n(<AdvancedSettingsEditor {...baseProps} settingsReadOnly />);
    expect(readOnly).not.toContain("Start from a scenario");
  });

  it("hides unselected on-chain options once deployed, keeping required ones", () => {
    // tokenized_security locks freeze/reclaim and marks scaledUiAmount recommended.
    const securityProps = { ...baseProps, category: "tokenized_security" as const, type: "equity" };

    // Editable draft: the recommended-but-unselected option is still offered.
    const editable = renderWithI18n(<AdvancedSettingsEditor {...securityProps} />);
    expect(editable).toContain("Scaled display amount");
    expect(editable).toContain("Freeze transfers");

    // Deployed (read-only): the unselected option is dropped; required stays.
    const deployed = renderWithI18n(<AdvancedSettingsEditor {...securityProps} settingsReadOnly />);
    expect(deployed).not.toContain("Scaled display amount");
    expect(deployed).toContain("Freeze transfers");
  });
});
