import { describe, expect, it, vi } from 'vitest';

vi.mock('../../../shared/state', async () => {
  const escapeHtml = (s: string) => s
    .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;').replace(/'/g, '&#39;');
  return { escapeHtml, popOutToTab: vi.fn(), isInTab: vi.fn(() => false), openVaultTab: vi.fn() };
});

import { renderSections } from '../fields';
import type { Item } from '../../../shared/types';

function itemWithSections(sections: Item['sections']): Item {
  return {
    id: 'aaaaaaaaaaaaaaaa',
    title: 'test',
    type: 'login',
    tags: [], favorite: false,
    created: 0, modified: 0,
    core: { type: 'login' },
    sections,
    attachments: [],
    field_history: {},
  };
}

describe('renderSections', () => {
  it('returns empty string when item has no sections', () => {
    const html = renderSections(itemWithSections([]), 'login');
    expect(html).toBe('');
  });

  it('skips sections with zero fields', () => {
    const html = renderSections(itemWithSections([
      { name: 'empty', fields: [] },
    ]), 'login');
    expect(html).not.toContain('empty');
  });

  it('renders a named section header + field rows', () => {
    const html = renderSections(itemWithSections([
      {
        name: 'recovery codes',
        fields: [
          { id: 'f0000001', label: 'code 1', kind: 'text',
            value: { kind: 'text', value: 'abc-123' }, hidden_by_default: false },
        ],
      },
    ]), 'login');
    expect(html).toContain('recovery codes');
    expect(html).toContain('code 1');
    expect(html).toContain('abc-123');
  });

  it('renders concealed password fields with unique ids', () => {
    const html = renderSections(itemWithSections([
      {
        name: 'backup',
        fields: [
          { id: 'f0000002', label: 'pin', kind: 'password',
            value: { kind: 'password', value: 'hunter2' }, hidden_by_default: true },
        ],
      },
    ]), 'login');
    expect(html).toContain('data-field-id="login-s0-f0"');
    expect(html).toContain('data-revealed="false"');
    expect(html).not.toMatch(/>hunter2</);
  });

  it('renders anonymous section with separator not header', () => {
    const html = renderSections(itemWithSections([
      {
        fields: [
          { id: 'f0000003', label: 'extra', kind: 'text',
            value: { kind: 'text', value: 'note' }, hidden_by_default: false },
        ],
      },
    ]), 'login');
    expect(html).toContain('section-separator');
    expect(html).not.toContain('section-header');
  });

  it('silently skips unsupported field kinds', () => {
    const html = renderSections(itemWithSections([
      {
        fields: [
          { id: 'f0000004', label: 'link', kind: 'url' as any,
            value: { kind: 'url', value: 'https://example.com' } as any,
            hidden_by_default: false },
          { id: 'f0000005', label: 'note', kind: 'text',
            value: { kind: 'text', value: 'kept' }, hidden_by_default: false },
        ],
      },
    ]), 'login');
    expect(html).not.toContain('https://example.com');
    expect(html).toContain('kept');
  });

  it('renders concealed fields for the concealed kind too', () => {
    const html = renderSections(itemWithSections([
      {
        fields: [
          { id: 'f0000006', label: 'secret', kind: 'concealed',
            value: { kind: 'concealed', value: 'shhh' }, hidden_by_default: true },
        ],
      },
    ]), 'login');
    expect(html).toContain('data-field-id="login-s0-f0"');
    expect(html).toContain('secret');
    expect(html).not.toMatch(/>shhh</);
  });
});
