// @vitest-environment jsdom
/**
 * Component tests for ServerTlsForm (settings → server.tls.*).
 *
 * Focus: port number serialization (parseInt, NaN → undefined), the
 * comma-separated HTTP-redirect-port list (single → number, many → array,
 * empty → undefined), and the enable-HTTPS checkbox round-trip.
 *
 * Note: these forms are controlled by an external `config` prop, but our test
 * `onChange` is a mock that never writes back, so the input's value never
 * advances across keystrokes. To exercise multi-character serialization we use
 * `fireEvent.change` to deliver the whole value in a single change event (which
 * is exactly the one transformation the component performs).
 */
import '../../test/dom-setup';
import { beforeAll, describe, it, expect, vi } from 'vitest';
import { screen, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { renderWithProviders } from '../../test/render-helpers';
import i18n from '../../i18n';
import { ServerTlsForm } from './ServerTlsForm';

beforeAll(async () => {
  await i18n.changeLanguage('en');
});

function render(config: any, onChange = vi.fn()) {
  renderWithProviders(
    <ServerTlsForm config={config} onChange={onChange} overriddenByEnv={{}} />,
  );
  return onChange;
}

// The redirect-port field placeholder contains a double space; match loosely.
const redirectPortField = () => screen.getByPlaceholderText(/9080.*or 80/);

describe('ServerTlsForm', () => {
  it('renders existing server.tls values', () => {
    render({
      server: {
        port: 9876,
        tls: { enabled: true, certFile: '/etc/ssl/server.pem', httpRedirectPort: [80, 9876] },
      },
    });
    expect(screen.getByDisplayValue('9876')).toBeInTheDocument();
    expect(screen.getByDisplayValue('/etc/ssl/server.pem')).toBeInTheDocument();
    // array redirect ports rendered joined
    expect(screen.getByDisplayValue('80, 9876')).toBeInTheDocument();
  });

  it('serializes server.port via parseInt', () => {
    const onChange = render({ server: { tls: {} } });
    const portInput = screen.getByPlaceholderText('9876');
    fireEvent.change(portInput, { target: { value: '8443' } });
    expect(onChange).toHaveBeenCalledWith('server.port', 8443);
  });

  it('parses a single redirect port to a number', () => {
    const onChange = render({ server: { tls: {} } });
    fireEvent.change(redirectPortField(), { target: { value: '80' } });
    expect(onChange).toHaveBeenLastCalledWith('server.tls.httpRedirectPort', 80);
  });

  it('parses a comma-separated redirect port list to an array', () => {
    const onChange = render({ server: { tls: {} } });
    fireEvent.change(redirectPortField(), { target: { value: '80, 9876' } });
    expect(onChange).toHaveBeenLastCalledWith('server.tls.httpRedirectPort', [80, 9876]);
  });

  it('clears redirect port to undefined when no valid number is present', () => {
    const onChange = render({ server: { tls: { httpRedirectPort: 80 } } });
    fireEvent.change(redirectPortField(), { target: { value: 'abc' } });
    expect(onChange).toHaveBeenLastCalledWith('server.tls.httpRedirectPort', undefined);
  });

  it('toggles the Serve-over-HTTPS checkbox', async () => {
    const user = userEvent.setup();
    const onChange = render({ server: { tls: {} } });
    const enableCheckbox = screen.getByLabelText('Serve over HTTPS');
    await user.click(enableCheckbox);
    expect(onChange).toHaveBeenCalledWith('server.tls.enabled', true);
  });
});
