function assert(condition: unknown, message = "assertion failed"): void {
  if (!condition) throw new Error(message);
}

import { renderToStaticMarkup } from "react-dom/server";
import SearchableSelect, {
  filterSearchableSelectOptions
} from "../src/components/SearchableSelect";
import {
  ReferenceMultiSelect,
  staticReferenceOptionProvider,
  wildcardReferenceOption
} from "../src/components/ReferenceSelect";
import SelectionList, { SelectionListItem } from "../src/components/SelectionList";
import { PlatformLanguageProvider } from "../src/i18n/LanguageContext";

function noop() {}

const markup = renderToStaticMarkup(
  <PlatformLanguageProvider>
    <SelectionList label="i18n:govoplan-core.notifications.753a22b2" className="domain-list" data-source="inbox">
      <SelectionListItem
        selected
        className="domain-row"
        draggable
        data-record-id="record-1"
        onDragStart={noop}
        onClick={noop}
      >
        <strong>Primary content</strong>
        <small>Supporting content</small>
      </SelectionListItem>
      <SelectionListItem selected={false} disabled>
        Disabled content
      </SelectionListItem>
    </SelectionList>
  </PlatformLanguageProvider>
);

assert(markup.includes('role="listbox"'), "the root exposes listbox semantics");
assert(markup.includes('class="selection-list domain-list"'), "root caller classes are preserved");
assert(markup.includes('data-source="inbox"'), "root native properties pass through");
assert(markup.includes('aria-label="Notifications"'), "the accessible label is translated");
assert(markup.includes('role="option"'), "items expose option semantics");
assert(markup.includes('aria-selected="true"'), "selected state is exposed accessibly");
assert(markup.includes('class="selection-list-item is-selected domain-row"'), "selected and domain classes are composed");
assert(markup.includes('draggable="true"'), "native draggable properties pass through");
assert(markup.includes('data-record-id="record-1"'), "native data properties pass through");
assert(markup.includes("<strong>Primary content</strong><small>Supporting content</small>"), "React node content is preserved");
assert(markup.includes('type="button"'), "items default to non-submitting buttons");
assert(markup.includes('aria-selected="false"'), "unselected state is exposed accessibly");
assert(markup.includes('aria-disabled="true"'), "disabled state is exposed accessibly");
assert(markup.includes('disabled=""'), "disabled state uses the native button contract");

const nativeLabelMarkup = renderToStaticMarkup(
  <SelectionList aria-label="Already translated">
    <SelectionListItem selected={false}>Content</SelectionListItem>
  </SelectionList>
);
assert(nativeLabelMarkup.includes('aria-label="Already translated"'), "native accessible labels pass through unchanged");

const directoryOptions = [
  {
    value: "account-1",
    label: "Ada Lovelace",
    description: "ada@example.test"
  },
  {
    value: "group-1",
    label: "Finance",
    searchText: "cost centre"
  }
];
assert(
  filterSearchableSelectOptions(directoryOptions, "example").length === 1,
  "searchable selects match option descriptions"
);
assert(
  filterSearchableSelectOptions(directoryOptions, "cost centre")[0]?.value ===
    "group-1",
  "searchable selects include explicit search aliases"
);

const searchableMarkup = renderToStaticMarkup(
  <PlatformLanguageProvider>
    <SearchableSelect
      id="assignment-target"
      aria-label="Assignment target"
      value="account-1"
      options={directoryOptions}
      onChange={() => undefined}
    />
  </PlatformLanguageProvider>
);
assert(
  searchableMarkup.includes('role="combobox"'),
  "searchable selects expose combobox semantics"
);
assert(
  searchableMarkup.includes('aria-controls="assignment-target-results"'),
  "searchable selects associate their input and result list"
);
assert(
  searchableMarkup.includes('value="Ada Lovelace"'),
  "searchable selects render labels instead of technical ids"
);

const referenceMarkup = renderToStaticMarkup(
  <PlatformLanguageProvider>
    <ReferenceMultiSelect
      id="policy-references"
      aria-label="Policy references"
      values={["group-1", "legacy-*", "removed"]}
      onChange={() => undefined}
      selectedOptions={[
        {
          value: "group-1",
          label: "Finance",
          description: "Access group"
        }
      ]}
      provider={staticReferenceOptionProvider([
        {
          value: "group-1",
          label: "Finance",
          description: "Access group"
        }
      ])}
      createCustomOption={(value) => wildcardReferenceOption(value)}
    />
  </PlatformLanguageProvider>
);
assert(
  referenceMarkup.includes("Finance"),
  "reference multi-selects render known labels"
);
assert(
  referenceMarkup.includes("Pattern"),
  "reference multi-selects distinguish wildcard patterns"
);
assert(
  referenceMarkup.includes("Unavailable reference"),
  "reference multi-selects retain unavailable values"
);
