import { describe, test, expect } from 'vitest';
import { FormContainer } from './FormContainer';

const toHtml = (FormContainer as any).toHtml;

describe('FormContainer.toHtml relay wiring', () => {
  test('with recipientEmail: marker + placeholder action + honeypot, forces POST', () => {
    const { html } = toHtml({ recipientEmail: 'a@b.com', thankYouUrl: '/thx', method: 'GET' }, '<input name="email">');
    expect(html).toMatch(/<!--WHP-FORM id="F_[0-9a-z]+" recipient="a@b.com" thankyou="\/thx"-->/);
    expect(html).toMatch(/action="__WHP_FORM_ACTION__F_[0-9a-z]+__"/);
    expect(html).toContain('method="POST"');            // relay forces POST even though method=GET
    expect(html).toContain('name="_gotcha"');
    // honeypot precedes the form's children
    expect(html.indexOf('_gotcha')).toBeLessThan(html.indexOf('name="email"'));
    // marker id === action id
    const mid = html.match(/id="(F_[0-9a-z]+)"/)![1];
    expect(html).toContain(`__WHP_FORM_ACTION__${mid}__`);
  });

  test('without recipientEmail: legacy action/method, no marker or honeypot', () => {
    const { html } = toHtml({ action: '/legacy', method: 'POST' }, '<input name="email">');
    expect(html).not.toContain('WHP-FORM');
    expect(html).not.toContain('_gotcha');
    expect(html).toContain('action="/legacy"');
    expect(html).toContain('<input name="email">');
  });

  test('same node id -> identical marker+placeholder ids across two calls', () => {
    const { html: html1 } = toHtml({ recipientEmail: 'a@b.com', thankYouUrl: '/thx' }, '<input name="email">', 'node-fc1');
    const { html: html2 } = toHtml({ recipientEmail: 'a@b.com', thankYouUrl: '/thx' }, '<input name="email">', 'node-fc1');
    expect(html1).toBe(html2);
  });

  test('two different node ids -> different fids', () => {
    const { html: html1 } = toHtml({ recipientEmail: 'a@b.com', thankYouUrl: '/thx' }, '<input name="email">', 'node-fc1');
    const { html: html2 } = toHtml({ recipientEmail: 'a@b.com', thankYouUrl: '/thx' }, '<input name="email">', 'node-fc2');
    const mid1 = html1.match(/<!--WHP-FORM id="([^"]+)"/)![1];
    const mid2 = html2.match(/<!--WHP-FORM id="([^"]+)"/)![1];
    expect(mid1).not.toBe(mid2);
  });
});

describe('FormContainer.toHtml method attribute sanitization', () => {
  test('malicious method value cannot break out of the attribute; falls back to POST', () => {
    const { html } = toHtml({ action: '/legacy', method: 'POST"><script>alert(1)</script>' }, '');
    expect(html).not.toContain('<script');
    expect(html).toContain('method="POST"');
  });

  test('legitimate GET method still passes through unchanged (non-relay path)', () => {
    const { html } = toHtml({ action: '/legacy', method: 'GET' }, '');
    expect(html).toContain('method="GET"');
  });
});

describe('FormContainer.toHtml box-model style passthrough', () => {
  test('margin/border/box-shadow/opacity flow through via the style prop', () => {
    const { html } = toHtml({ action: '/legacy', style: { marginTop: '20px', border: '3px dashed #ccc', boxShadow: '0 4px 8px rgba(0,0,0,.2)', opacity: '0.95' } }, '');
    expect(html).toContain('margin-top:20px');
    expect(html).toContain('border:3px dashed #ccc');
    expect(html).toContain('opacity:0.95');
  });
});

describe('FormContainer.craft.props includes animation/visibility defaults', () => {
  test('has blank/false defaults', () => {
    expect(FormContainer.craft!.props).toMatchObject({
      animation: '', animationDelay: '', hideOnDesktop: false, hideOnTablet: false, hideOnMobile: false,
    });
  });
});
