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

import type { PageDSL6 } from '../../../types/index.js';
import { findNextWidgetNameWithSuffix, findAllInstancesOfWidgetNameWithPrefix } from './migrateToSections.js';

describe('findNextWidgetNameWithSuffix', () => {
  it('generates a name with a default suffix or none', () => {
    // Numbers start at 1
    const result = findNextWidgetNameWithSuffix('TestWidget', []);
    expect(result).toBe('TestWidget1');
    const result2 = findNextWidgetNameWithSuffix('TestWidget', ['TestWidget1']);
    expect(result2).toBe('TestWidget2');

    // Suffix start with no suffix
    const result3 = findNextWidgetNameWithSuffix('TestWidget', [], '_');
    expect(result3).toBe('TestWidget');
    const result4 = findNextWidgetNameWithSuffix('TestWidget', ['TestWidget'], '_');
    expect(result4).toBe('TestWidget_');
  });

  it('generates a name with the right suffix when multiple instances of the name exist', () => {
    const existingNames = ['testwidget', 'testwidget_', 'testwidget__'];
    const result = findNextWidgetNameWithSuffix('TestWidget', existingNames, '_');
    expect(result).toBe('TestWidget___');
  });

  it('generates a name with the right suffix when multiple instances of the name exist and the suffix string arg is undefined', () => {
    const existingNames = ['testwidget', 'testwidget_', 'testwidget__'];
    const result = findNextWidgetNameWithSuffix('TestWidget', existingNames);
    expect(result).toBe('TestWidget1');
  });

  it('generates a name with the right suffix when a name with a numeric suffix exists and the suffix string arg is undefined', () => {
    const existingNames = ['TestWidget', 'TestWidget1'];
    const result = findNextWidgetNameWithSuffix('TestWidget', existingNames);
    expect(result).toBe('TestWidget2');
  });

  it('generates a name without the suffix when one instance already exists', () => {
    const existingNames = ['testwidget'];
    const result = findNextWidgetNameWithSuffix('TestWidget', existingNames, '_myfunnysuffix_');
    expect(result).toBe('TestWidget_myfunnysuffix_');
  });
});

describe('findAllInstancesOfWidgetNameWithPrefix', () => {
  it('should find widget names with the given prefix', () => {
    const dsl = {
      widgetName: 'prefixOne',
      children: [{ widgetName: 'prefixTwo' }, { widgetName: 'otherName' }]
    };

    const result = findAllInstancesOfWidgetNameWithPrefix(dsl as PageDSL6, 'prefix');
    expect(result).toEqual(['prefixOne', 'prefixTwo']);
  });

  it('should handle deeply nested widget structures', () => {
    const dsl = {
      widgetName: 'root',
      children: [
        {
          widgetName: 'level1',
          children: [
            {
              widgetName: 'prefixNested',
              children: [{ widgetName: 'prefixDeeplyNested' }]
            }
          ]
        }
      ]
    };

    const result = findAllInstancesOfWidgetNameWithPrefix(dsl as PageDSL6, 'prefix');
    expect(result).toEqual(['prefixNested', 'prefixDeeplyNested']);
  });

  it('should return an empty array when there are no matches', () => {
    const dsl = {
      widgetName: 'rootName',
      children: [{ widgetName: 'childOne' }, { widgetName: 'childTwo' }]
    };

    const result = findAllInstancesOfWidgetNameWithPrefix(dsl as PageDSL6, 'prefix');
    expect(result).toEqual([]);
  });
});
