import { describe, it, expect, beforeEach, vi } from 'vitest';
import {
  loadColorScheme, saveColorScheme, resetColorScheme, applyColorScheme,
  DEFAULT_DIGIT_COLOR, DEFAULT_SYMBOL_COLOR,
} from '../color-scheme';

function mockChromeStorage(initial: any = {}) {
  const store = { ...initial };
  (global as any).chrome = {
    storage: {
      sync: {
        get: vi.fn((key: string) => Promise.resolve(
          key in store ? { [key]: store[key] } : {})),
        set: vi.fn((kv: any) => { Object.assign(store, kv); return Promise.resolve(); }),
        remove: vi.fn((key: string) => { delete store[key]; return Promise.resolve(); }),
      },
    },
  };
  return store;
}

describe('color-scheme storage', () => {
  beforeEach(() => {
    // happy-dom provides document globally; reset inline styles between tests
    document.documentElement.removeAttribute('style');
  });

  it('load returns defaults when storage is empty', async () => {
    mockChromeStorage();
    const scheme = await loadColorScheme();
    expect(scheme.digit_color).toBe(DEFAULT_DIGIT_COLOR);
    expect(scheme.symbol_color).toBe(DEFAULT_SYMBOL_COLOR);
  });

  it('load returns stored values when present', async () => {
    mockChromeStorage({
      password_display_scheme: { digit_color: '#123456', symbol_color: '#abcdef' },
    });
    const scheme = await loadColorScheme();
    expect(scheme.digit_color).toBe('#123456');
    expect(scheme.symbol_color).toBe('#abcdef');
  });

  it('save round-trips', async () => {
    mockChromeStorage();
    await saveColorScheme({ digit_color: '#111111', symbol_color: '#222222' });
    const scheme = await loadColorScheme();
    expect(scheme).toEqual({ digit_color: '#111111', symbol_color: '#222222' });
  });

  it('reset removes the storage key', async () => {
    const store = mockChromeStorage({
      password_display_scheme: { digit_color: '#000000', symbol_color: '#ffffff' },
    });
    await resetColorScheme();
    expect(store.password_display_scheme).toBeUndefined();
    const scheme = await loadColorScheme();
    expect(scheme.digit_color).toBe(DEFAULT_DIGIT_COLOR);
  });

  it('apply sets CSS custom properties on document.documentElement', async () => {
    mockChromeStorage({
      password_display_scheme: { digit_color: '#deadbe', symbol_color: '#feed00' },
    });
    await applyColorScheme();
    const root = document.documentElement.style;
    expect(root.getPropertyValue('--relicario-pwd-digit-color').trim()).toBe('#deadbe');
    expect(root.getPropertyValue('--relicario-pwd-symbol-color').trim()).toBe('#feed00');
  });

  it('save rejects malformed hex values', async () => {
    mockChromeStorage();
    await expect(saveColorScheme({ digit_color: 'not-a-color', symbol_color: '#ffffff' }))
      .rejects.toThrow();
  });
});
