import { beforeEach, describe, expect, it } from 'vitest';
import { defaultSettings } from '@core/settings';
import { useUserSettingsStore } from './UserSettingsStore';

/** The managed slice (editor/performance/formatting) of a full settings record. */
function managed(s = defaultSettings()) {
  return { editor: s.editor, performance: s.performance, formatting: s.formatting };
}

beforeEach(() => {
  useUserSettingsStore.getState().hydrate(defaultSettings());
});

describe('UserSettingsStore', () => {
  it('hydrate strips a full record to the managed slice', () => {
    useUserSettingsStore.getState().hydrate(defaultSettings());
    expect(useUserSettingsStore.getState().saved).toEqual(managed());
  });

  it('setters apply live and patch only their cluster', () => {
    useUserSettingsStore.getState().setEditor({ fontSize: 16 });
    expect(useUserSettingsStore.getState().saved.editor.fontSize).toBe(16);
    // other editor fields and other clusters untouched
    expect(useUserSettingsStore.getState().saved.editor.tabSize).toBe(2);
    expect(useUserSettingsStore.getState().saved.performance.renderDebounce).toBe(1500);

    useUserSettingsStore.getState().setPerformance({ renderDebounce: 800 });
    expect(useUserSettingsStore.getState().saved.performance.renderDebounce).toBe(800);

    useUserSettingsStore.getState().setFormatting({ dateFormat: 'iso' });
    expect(useUserSettingsStore.getState().saved.formatting.dateFormat).toBe('iso');
  });

  it('each setter produces a fresh `saved` reference (drives the persistence subscriber)', () => {
    const before = useUserSettingsStore.getState().saved;
    useUserSettingsStore.getState().setEditor({ minimap: true });
    const after = useUserSettingsStore.getState().saved;
    expect(after).not.toBe(before);
    expect(after.editor.minimap).toBe(true);
  });

  it('resetEditor restores only the editor cluster to defaults', () => {
    useUserSettingsStore.getState().setEditor({ fontSize: 18, minimap: true, tabSize: 8 });
    useUserSettingsStore.getState().setFormatting({ dateFormat: 'iso' });

    useUserSettingsStore.getState().resetEditor();

    expect(useUserSettingsStore.getState().saved.editor).toEqual(defaultSettings().editor);
    // formatting (a different cluster) is left as the user set it
    expect(useUserSettingsStore.getState().saved.formatting.dateFormat).toBe('iso');
  });

  it('does not alias the stored record on hydrate (mutating input later is inert)', () => {
    const input = defaultSettings();
    useUserSettingsStore.getState().hydrate(input);
    input.editor.fontSize = 99;
    expect(useUserSettingsStore.getState().saved.editor.fontSize).toBe(12);
  });
});
