import { describe, it, expect } from 'vitest';
import { parseColor, deriveSpaceBrandVars } from './spaceBranding';

describe('parseColor', () => {
  it('parses 6-digit hex', () => {
    expect(parseColor('#2563eb')).toEqual({ r: 0x25, g: 0x63, b: 0xeb });
  });
  it('parses 3-digit hex (expands)', () => {
    expect(parseColor('#abc')).toEqual({ r: 0xaa, g: 0xbb, b: 0xcc });
  });
  it('parses rgb()/rgba()', () => {
    expect(parseColor('rgb(10, 20, 30)')).toEqual({ r: 10, g: 20, b: 30 });
    expect(parseColor('rgba(10,20,30,0.5)')).toEqual({ r: 10, g: 20, b: 30 });
  });
  it('returns null for unparsable input', () => {
    expect(parseColor('not-a-color')).toBeNull();
    expect(parseColor('')).toBeNull();
  });
});

describe('deriveSpaceBrandVars', () => {
  it('returns null for unparsable color', () => {
    expect(deriveSpaceBrandVars('garbage', false)).toBeNull();
  });

  it('derives all 5 CSS vars and echoes the raw primary', () => {
    const vars = deriveSpaceBrandVars('#2563eb', false)!;
    expect(vars).not.toBeNull();
    expect(vars['--brand-primary']).toBe('#2563eb');
    expect(vars['--brand-primary-deep']).toMatch(/^hsl\(/);
    expect(vars['--brand-primary-soft']).toMatch(/^hsl\(/);
    expect(vars['--brand-primary-ring']).toBe('rgba(37, 99, 235, 0.35)');
    expect(['#0f172a', '#ffffff']).toContain(vars['--brand-primary-fg']);
  });

  it('picks a dark fg for a light brand color and white fg for a dark one', () => {
    // near-white brand → dark text
    expect(deriveSpaceBrandVars('#f5f5f5', false)!['--brand-primary-fg']).toBe('#0f172a');
    // dark brand → white text
    expect(deriveSpaceBrandVars('#1e293b', false)!['--brand-primary-fg']).toBe('#ffffff');
  });

  it('uses a deeper soft tint in dark mode than in light mode', () => {
    const light = deriveSpaceBrandVars('#2563eb', false)!['--brand-primary-soft'];
    const dark = deriveSpaceBrandVars('#2563eb', true)!['--brand-primary-soft'];
    // light soft lightness ~95%, dark soft lightness = 10%
    const lightL = Number(light.match(/(\d+(?:\.\d+)?)%\)$/)![1]);
    const darkL = Number(dark.match(/(\d+(?:\.\d+)?)%\)$/)![1]);
    expect(darkL).toBeLessThan(lightL);
    expect(darkL).toBeCloseTo(10, 0);
  });

  it('deep tint is darker than the primary lightness (hover affordance)', () => {
    // #808080 → l=50% → deep l=38%
    const deep = deriveSpaceBrandVars('#808080', false)!['--brand-primary-deep'];
    const deepL = Number(deep.match(/(\d+(?:\.\d+)?)%\)$/)![1]);
    expect(deepL).toBeCloseTo(38, 0);
  });
});
