import { useEffect, useRef } from "react";
import { DEFAULT_REGEX_LIMITS } from "../regex/execution/request-limits";
import {
  DEFAULT_GENERATION_SETTINGS,
  GENERATION_LIMITS,
} from "../regex/generation/generation-limits";
import { manifest } from "../toolbox/manifest";

const releaseSourceUrl = `https://git.add-ideas.de/zemion/regex-tools/src/tag/v${manifest.version}`;

export function HelpDialog({
  open,
  onClose,
}: {
  readonly open: boolean;
  readonly onClose: () => void;
}) {
  const dialog = useRef<HTMLDialogElement>(null);
  useEffect(() => {
    const element = dialog.current;
    if (!element) return;
    if (open && !element.open) element.showModal();
    if (!open && element.open) element.close();
  }, [open]);
  return (
    <dialog
      ref={dialog}
      className="app-dialog"
      aria-labelledby="help-title"
      onClose={onClose}
    >
      <header>
        <div>
          <p className="eyebrow">Regex Tools {manifest.version}</p>
          <h2 id="help-title">Local regex workbench</h2>
        </div>
        <button
          type="button"
          className="icon-button"
          aria-label="Close help"
          onClick={onClose}
        >
          ×
        </button>
      </header>
      <div className="dialog-content">
        <section>
          <h3>What runs where</h3>
          <p>
            Syntax parsing and active-engine execution run in separate, killable
            browser workers. JavaScript uses the browser&apos;s ECMAScript
            RegExp implementation, while the standalone PCRE2 profile uses the
            bundled 10.47 WebAssembly engine. The other profiles name their
            selected runtime explicitly: PHP 8.5.8 preg with PCRE2 10.44, legacy
            Perl 5.28.1 through WebPerl 0.09-beta, CPython 3.14, CRuby 4.0,
            TeaVM java.util.regex, libc++ std::regex, Go regexp, Rust regex and
            .NET System.Text.RegularExpressions. Scala is explicitly a Scala/JVM
            regex-syntax compatibility profile over the same TeaVM Java runtime,
            not a Scala VM. Result metadata names the runtime actually used.
          </p>
          <p>
            Structural coverage varies by profile. Only the ECMAScript provider
            currently exposes a complete grammar-backed tree; the additional
            community providers retain partial lexical captures and replacement
            tokens while their selected runtime compiler remains authoritative.
            Patterns, subjects and projects are never uploaded. There is no
            backend, account, telemetry, CDN dependency, or executable
            replacement function.
          </p>
          <p>
            TeaVM 0.15.0 is not OpenJDK. Its replacement implementation accepts
            single-digit $n references, so $12 means $1 followed by literal 2.
            Java SE ${"{name}"} references are reported as unavailable.
          </p>
        </section>
        <section>
          <h3>Trees and replacement mapping</h3>
          <p>
            The explanation tree is deterministic structure derived from the
            syntax provider. The extraction tree contains actual browser-engine
            matches and captures. Replacement mode adds a typed token tree and
            bounded per-match contribution/range mapping over those actual
            matches. These views are not internal engine traces. The separate
            PCRE trace viewer shows actual bounded automatic callouts reported
            by PCRE2; its adjacent-position movement labels are derived and it
            is not a complete record of every internal action. Browser
            ECMAScript exposes no corresponding V8, SpiderMonkey or
            JavaScriptCore trace API.
          </p>
        </section>
        <section>
          <h3>Advisory analysis</h3>
          <p>
            Static risk findings are ECMAScript-2025-specific heuristics, and
            generated-input growth observations describe only the selected
            bounded samples. Neither proves safety or general complexity. Growth
            and cold/warm benchmark timing run in a separate killable worker and
            never include the PCRE2 trace path.
          </p>
        </section>
        <section>
          <h3>Generated cases</h3>
          <p>
            ECMAScript generator v1 deterministically samples supported
            normalized-AST paths from an explicit seed. Every intended positive
            and negative subject runs through the selected actual engine before
            it can become a test; candidates with the wrong outcome are
            discarded. The coverage report names unsupported constructs.
            Sampling is not proof of complete language coverage. Other flavours
            remain unavailable until their structural providers expose the
            required AST; their syntax is never reinterpreted as ECMAScript.
          </p>
        </section>
        <section>
          <h3>Pattern formatting</h3>
          <p>
            The ECMAScript formatter makes only grammar-backed literal/control
            escape changes; it does not insert layout whitespace or reinterpret
            another flavour&apos;s syntax. Applying a preview requires
            independent source and candidate reparsing, actual-engine
            match/replacement comparison, every applicable exact unit test, and
            an explicit confirmation. Passing bounded checks is evidence for
            those snapshots, not proof for every possible subject.
          </p>
        </section>
        <section>
          <h3>Timeouts and limits</h3>
          <dl className="help-limits">
            <div>
              <dt>Live execution</dt>
              <dd>{DEFAULT_REGEX_LIMITS.liveExecutionTimeoutMs} ms</dd>
            </div>
            <div>
              <dt>Manual execution</dt>
              <dd>{DEFAULT_REGEX_LIMITS.manualExecutionTimeoutMs} ms</dd>
            </div>
            <div>
              <dt>Maximum matches</dt>
              <dd>{DEFAULT_REGEX_LIMITS.maximumMatches.toLocaleString()}</dd>
            </div>
            <div>
              <dt>Maximum capture rows</dt>
              <dd>
                {DEFAULT_REGEX_LIMITS.maximumCaptureRows.toLocaleString()}
              </dd>
            </div>
            <div>
              <dt>Maximum capture groups</dt>
              <dd>
                {DEFAULT_REGEX_LIMITS.maximumCaptureGroups.toLocaleString()}
              </dd>
            </div>
            <div>
              <dt>Replacement template</dt>
              <dd>
                {DEFAULT_REGEX_LIMITS.maximumReplacementTemplateUtf16.toLocaleString()}{" "}
                UTF-16 units
              </dd>
            </div>
            <div>
              <dt>List template</dt>
              <dd>
                {DEFAULT_REGEX_LIMITS.maximumListTemplateUtf16.toLocaleString()}{" "}
                UTF-16 units
              </dd>
            </div>
            <div>
              <dt>Unit-test suite wall time</dt>
              <dd>60 seconds</dd>
            </div>
            <div>
              <dt>Corpus input</dt>
              <dd>
                {DEFAULT_REGEX_LIMITS.maximumCorpusDocuments.toLocaleString()}{" "}
                documents · {DEFAULT_REGEX_LIMITS.corpusHardBytes / 1024 / 1024}{" "}
                MiB
              </dd>
            </div>
            <div>
              <dt>Corpus wall time</dt>
              <dd>
                {DEFAULT_REGEX_LIMITS.maximumCorpusWallTimeMs / 60_000} minutes
              </dd>
            </div>
            <div>
              <dt>Analysis wall time</dt>
              <dd>
                {DEFAULT_REGEX_LIMITS.maximumBenchmarkWallTimeMs / 1_000}{" "}
                seconds
              </dd>
            </div>
            <div>
              <dt>Benchmark iteration cap</dt>
              <dd>
                {DEFAULT_REGEX_LIMITS.maximumBenchmarkIterations.toLocaleString()}
              </dd>
            </div>
            <div>
              <dt>Growth probe steps</dt>
              <dd>24</dd>
            </div>
            <div>
              <dt>Generated cases</dt>
              <dd>
                {DEFAULT_REGEX_LIMITS.maximumGeneratedCases.toLocaleString()}{" "}
                retained ·{" "}
                {GENERATION_LIMITS.maximumCandidateAttempts.toLocaleString()}{" "}
                attempts
              </dd>
            </div>
            <div>
              <dt>Generation defaults</dt>
              <dd>
                {DEFAULT_GENERATION_SETTINGS.perCaseTimeoutMs} ms per case ·{" "}
                {DEFAULT_GENERATION_SETTINGS.maximumWallTimeMs / 1_000} seconds
                aggregate
              </dd>
            </div>
            <div>
              <dt>Generated subject text</dt>
              <dd>
                {GENERATION_LIMITS.maximumTotalSubjectBytes / 1024 / 1024} MiB
                aggregate hard cap
              </dd>
            </div>
            <div>
              <dt>Formatter validation</dt>
              <dd>1,000 tests · 60 seconds aggregate</dd>
            </div>
            <div>
              <dt>Independent corpus lines</dt>
              <dd>
                {DEFAULT_REGEX_LIMITS.maximumCorpusLines.toLocaleString()}
              </dd>
            </div>
            <div>
              <dt>Corpus applied output</dt>
              <dd>
                {DEFAULT_REGEX_LIMITS.maximumCorpusOutputBytes / 1024 / 1024}{" "}
                MiB
              </dd>
            </div>
          </dl>
          <p>
            A timeout terminates the worker. It means “timed out”, never “no
            match”. The following run uses a fresh worker.
          </p>
        </section>
        <section>
          <h3>Persistence</h3>
          <p>
            Ad-hoc test text is excluded from local saves and exports by
            default. Test definitions are deliberate project data. Import is
            validated and paused until you review and run it. Corpus documents,
            contents, outputs and results are always ephemeral and excluded from
            projects and IndexedDB. Analysis settings and results are likewise
            ephemeral. Generated-case settings and review results are ephemeral;
            only cases explicitly added to the test suite persist, together with
            their bounded seed and generator provenance. Test subjects remain
            excluded unless separately opted in. Formatter previews and
            validation observations are ephemeral; only an explicitly applied
            pattern enters workbench/project state.
          </p>
        </section>
        <section>
          <h3>Legal notice</h3>
          <p>
            Copyright © 2026 Albrecht Degering. Regex Tools is free software:
            you may redistribute it and/or modify it under the terms of the GNU
            General Public License, version 3 or (at your option) any later
            version. It comes without any warranty, to the extent permitted by
            law.
          </p>
          <p>
            Read the{" "}
            <a href="./LICENSE" target="_blank" rel="noreferrer">
              complete licence
            </a>{" "}
            or inspect and obtain the{" "}
            <a href={releaseSourceUrl} target="_blank" rel="noreferrer">
              corresponding source code
            </a>
            .
          </p>
        </section>
      </div>
      <footer>
        <button type="button" className="primary-button" onClick={onClose}>
          Close
        </button>
      </footer>
    </dialog>
  );
}
