import { useMemo, useState } from "react";
import type { RegexFlavourId } from "../regex/model/flavour";
import {
  ECMASCRIPT_REFERENCE,
  PCRE2_REFERENCE,
} from "../regex/reference/token-reference";

export function QuickReference({
  onUsePattern,
  onClose,
  flavour = "ecmascript",
}: {
  readonly onUsePattern: (syntax: string) => void;
  readonly onClose?: () => void;
  readonly flavour?: RegexFlavourId;
}) {
  const [query, setQuery] = useState("");
  const reference =
    flavour === "pcre2" ? PCRE2_REFERENCE : ECMASCRIPT_REFERENCE;
  const entries = useMemo(() => {
    const normalizeSearchText = (value: string) =>
      value
        .toLocaleLowerCase()
        .replaceAll(/[^\p{L}\p{N}]+/gu, " ")
        .trim();
    const needle = normalizeSearchText(query);
    return needle
      ? reference.filter((entry) =>
          normalizeSearchText(
            [
              entry.construct,
              entry.syntax,
              entry.explanation,
              entry.example,
              entry.flags.join(" "),
              entry.source,
            ].join(" "),
          ).includes(needle),
        )
      : reference;
  }, [query, reference]);
  return (
    <section
      className="panel reference-panel"
      aria-labelledby="reference-heading"
    >
      <header className="panel-heading">
        <div>
          <p className="eyebrow">
            Original {flavour === "pcre2" ? "PCRE2" : "ECMAScript"} reference
          </p>
          <h2 id="reference-heading">Quick reference</h2>
        </div>
        <div className="panel-heading-actions">
          <span>
            {entries.length} of {reference.length} constructs
          </span>
          {onClose ? (
            <button
              type="button"
              className="icon-button"
              aria-label="Close quick reference"
              data-dialog-initial-focus
              onClick={onClose}
            >
              ×
            </button>
          ) : null}
        </div>
      </header>
      <label className="stacked-control">
        <span>Filter constructs</span>
        <input
          type="search"
          value={query}
          onChange={(event) => setQuery(event.target.value)}
        />
      </label>
      {entries.length > 0 ? (
        <ul className="reference-list">
          {entries.map((entry) => (
            <li key={entry.id}>
              <div>
                <strong>{entry.construct}</strong>
                <code>{entry.syntax}</code>
              </div>
              <p>{entry.explanation}</p>
              <dl className="reference-meta">
                <div>
                  <dt>Flavour</dt>
                  <dd>{entry.flavours.join(", ")}</dd>
                </div>
                <div>
                  <dt>Relevant flags</dt>
                  <dd>
                    {entry.flags.length > 0 ? entry.flags.join(", ") : "None"}
                  </dd>
                </div>
                <div>
                  <dt>Example</dt>
                  <dd>
                    <code>{entry.example}</code>
                  </dd>
                </div>
                <div>
                  <dt>Source</dt>
                  <dd>
                    <a href={entry.sourceUrl} target="_blank" rel="noreferrer">
                      {entry.source}
                    </a>
                  </dd>
                </div>
              </dl>
              {entry.caveat ? <small>{entry.caveat}</small> : null}
              <button
                type="button"
                className="secondary-button"
                onClick={() => onUsePattern(entry.example)}
              >
                Use example as pattern
              </button>
            </li>
          ))}
        </ul>
      ) : (
        <p className="empty-state" role="status">
          No reference constructs match “{query.trim()}”.
        </p>
      )}
    </section>
  );
}
