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

import { hexToHslComponents, isSafeHex, readableForegroundHsl } from './branding';

describe('hexToHslComponents', () => {
  it('converts a 6-char hex to "H S% L%"', () => {
    expect(hexToHslComponents('#ff0000')).toBe('0 100% 50%');
    expect(hexToHslComponents('#00ff00')).toBe('120 100% 50%');
    expect(hexToHslComponents('#0000ff')).toBe('240 100% 50%');
  });

  it('expands and converts a 3-char shorthand hex', () => {
    expect(hexToHslComponents('#f00')).toBe('0 100% 50%');
    expect(hexToHslComponents('#fff')).toBe('0 0% 100%');
    expect(hexToHslComponents('#000')).toBe('0 0% 0%');
  });

  it('accepts hex without leading "#"', () => {
    expect(hexToHslComponents('ff0000')).toBe('0 100% 50%');
  });

  it('is case insensitive', () => {
    expect(hexToHslComponents('#FF0000')).toBe('0 100% 50%');
    expect(hexToHslComponents('#aAbBcC')).toBe(hexToHslComponents('#AABBCC'));
  });

  it('returns null for invalid input', () => {
    expect(hexToHslComponents('')).toBeNull();
    expect(hexToHslComponents(null)).toBeNull();
    expect(hexToHslComponents(undefined)).toBeNull();
    expect(hexToHslComponents('not a hex')).toBeNull();
    expect(hexToHslComponents('#xyz')).toBeNull();
    expect(hexToHslComponents('#ff00')).toBeNull(); // wrong length
    expect(hexToHslComponents('rgb(255,0,0)')).toBeNull();
  });

  it('handles a non-saturated grey', () => {
    // Grey should round-trip with 0% saturation regardless of lightness.
    expect(hexToHslComponents('#808080')).toMatch(/^0 0% 50%$/);
  });

  it('refuses tokens that pass shape but contain non-hex characters', () => {
    // Pure shape `#xxxxxx` would fool a length-only check; the regex must catch it.
    expect(hexToHslComponents('#zzzzzz')).toBeNull();
  });
});

describe('readableForegroundHsl', () => {
  it('returns near-black on bright colors', () => {
    expect(readableForegroundHsl('#ffff00')).toBe('220 25% 10%'); // bright yellow
    expect(readableForegroundHsl('#ffffff')).toBe('220 25% 10%'); // white
  });

  it('returns white on dark colors', () => {
    expect(readableForegroundHsl('#000000')).toBe('0 0% 100%');
    expect(readableForegroundHsl('#3300ff')).toBe('0 0% 100%');
  });

  it('falls back to white for invalid input', () => {
    expect(readableForegroundHsl(null)).toBe('0 0% 100%');
    expect(readableForegroundHsl('')).toBe('0 0% 100%');
    expect(readableForegroundHsl('garbage')).toBe('0 0% 100%');
  });
});

describe('isSafeHex', () => {
  it('accepts 3-char and 6-char hex', () => {
    expect(isSafeHex('#abc')).toBe(true);
    expect(isSafeHex('#abcdef')).toBe(true);
    expect(isSafeHex('abc')).toBe(true);
  });

  it('rejects malformed input', () => {
    expect(isSafeHex(null)).toBe(false);
    expect(isSafeHex(undefined)).toBe(false);
    expect(isSafeHex('')).toBe(false);
    expect(isSafeHex('#zzz')).toBe(false);
    expect(isSafeHex('rgb(255,0,0)')).toBe(false);
    // CSS injection attempt — must be rejected before going into a style attr.
    expect(isSafeHex('red; background: url(evil)')).toBe(false);
  });
});
