// @vitest-environment happy-dom
//
// The Help modal sizes to its content (opening a pill grows it, capped by
// .app-modal's max-height), and app-modal--help gives its body the symmetric
// spacing the version footer needs: equal gaps above the list, between the
// list and the version line, and below it. The revert answer is two
// paragraphs rather than one wall of text.
import { act } from 'react';
import { createRoot } from 'react-dom/client';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { HelpModal } from './HelpModal';
import { CLIENT_VERSION } from '../../version';

let container;

beforeEach(() => {
  container = document.createElement('div');
  document.body.appendChild(container);
});

afterEach(() => {
  document.body.removeChild(container);
  container = null;
});

function render() {
  const root = createRoot(container);
  act(() => root.render(<HelpModal onClose={() => {}} />));
  return root;
}

const questionButton = (text) =>
  [...container.querySelectorAll('.help-faq-question')].find((b) => b.textContent.includes(text));

describe('HelpModal', () => {
  it('carries the help spacing variant and no fixed height', () => {
    render();
    const className = container.querySelector('.app-modal').className;
    expect(className).toContain('app-modal--help');
    // The modal must size to its content — a fixed-height variant would stop
    // it growing when a pill opens.
    expect(className).not.toContain('app-modal--tall');
  });

  it('renders the version footer with a fainter version number', () => {
    render();
    const footer = container.querySelector('.help-version');
    // Asserted against the shared constant, not a literal: this line was a
    // hardcoded '0.1.0' that survived the 0.2.0 bump, and a literal here
    // would go stale in exactly the same way.
    expect(footer.textContent).toBe(`Cambium ${CLIENT_VERSION}`);
    expect(footer.querySelector('.help-version-number').textContent).toBe(CLIENT_VERSION);
  });

  it('shows the version the rest of the app reports, never a stale literal', () => {
    render();
    const shown = container.querySelector('.help-version-number').textContent;
    // Guards the wiring itself: a regression to a typed-in string would still
    // satisfy the test above only if it happened to match, so pin the shape
    // and the fact that it tracks package.json.
    expect(shown).toMatch(/^\d+\.\d+\.\d+$/);
    expect(shown).toBe(CLIENT_VERSION);
  });

  it('renders the copyright line under the version', () => {
    render();
    const copyright = container.querySelector('.help-copyright');
    expect(copyright.textContent).toBe('© Ridgeway Interactive 2026');
    // Must follow the version line, not precede it.
    expect(
      container.querySelector('.help-version').compareDocumentPosition(copyright)
        & Node.DOCUMENT_POSITION_FOLLOWING
    ).toBeTruthy();
  });

  it('splits the revert answer into two paragraphs', () => {
    render();
    act(() => questionButton('What does reverting mean?').click());
    const answers = [...container.querySelectorAll('.help-faq-answer')];
    expect(answers).toHaveLength(2);
    expect(answers[0].textContent).toContain('resets it to the server’s version');
    expect(answers[1].textContent).toContain('will perform a rollback');
  });

  it('still renders single-paragraph answers as one paragraph', () => {
    render();
    act(() => questionButton('What is checking out?').click());
    expect(container.querySelectorAll('.help-faq-answer')).toHaveLength(1);
  });
});
