import { EditorSchemaService } from './editor-schema.service';
import { ALL_FIELD_SCHEMAS } from './editor-schema';

describe('EditorSchemaService', () => {
  let service: EditorSchemaService;

  beforeEach(() => {
    service = new EditorSchemaService();
  });

  it('returns the fields declared for a section', () => {
    const themeFields = service.getFields('theme');
    expect(themeFields.length).toBeGreaterThan(0);
    expect(themeFields.every(field => field.section === 'theme')).toBeTrue();
    expect(themeFields.some(field => field.key === 'theme.palette.primary')).toBeTrue();
  });

  it('returns an empty array for a section with no fields', () => {
    expect(service.getFields('preview')).toEqual([]);
  });

  it('looks up a field by dot-path key', () => {
    const field = service.getField('theme.palette.primary');
    expect(field).toBeDefined();
    expect(field?.type).toBe('color');
    expect(field?.validators?.some(validator => validator.name === 'hexColor')).toBeTrue();
  });

  it('exposes every field via all()', () => {
    expect(service.all()).toBe(ALL_FIELD_SCHEMAS);
    expect(service.all().length).toBe(ALL_FIELD_SCHEMAS.length);
  });

  it('resolves nested dot-path values against a source object', () => {
    const source = { theme: { palette: { primary: '#497671' } } };
    expect(service.getByPath(source, 'theme.palette.primary')).toBe('#497671');
  });

  it('returns undefined when a dot-path segment is missing instead of throwing', () => {
    const source = { theme: {} };
    expect(service.getByPath(source, 'theme.palette.primary')).toBeUndefined();
    expect(service.getByPath(null, 'theme.palette.primary')).toBeUndefined();
  });

  it('declares no duplicate keys within a single section', () => {
    for (const field of ALL_FIELD_SCHEMAS) {
      const sameSection = ALL_FIELD_SCHEMAS.filter(
        candidate => candidate.section === field.section && candidate.key === field.key,
      );
      expect(sameSection.length).withContext(`${field.section}:${field.key}`).toBe(1);
    }
  });
});
