import { describe, it, expect } from 'vitest';
import { hexToContainer, hexToOnContainer, deriveScheduleXColors } from './colorUtils.js';

describe('colorUtils', () => {
  describe('hexToContainer — 15% opacity blend over white', () => {
    it('produces a lighter color than the input', () => {
      const container = hexToContainer('#4A90D9');
      // Container should be lighter (higher R, G, B values) than original
      // #4A90D9 = rgb(74, 144, 217). At 15% over white:
      //   R = 74 * 0.15 + 255 * 0.85 = 11.1 + 216.75 ≈ 228 → #E4
      //   G = 144 * 0.15 + 255 * 0.85 = 21.6 + 216.75 ≈ 238 → #EE
      //   B = 217 * 0.15 + 255 * 0.85 = 32.55 + 216.75 ≈ 249 → #F9
      expect(container).toMatch(/^#[0-9a-f]{6}$/i);
      const [r, g, b] = hexToRgbTest(container);
      // Should be well above 200 in all channels (very light)
      expect(r).toBeGreaterThan(200);
      expect(g).toBeGreaterThan(200);
      expect(b).toBeGreaterThan(200);
    });

    it('blends #4A90D9 at 15% over white correctly', () => {
      const container = hexToContainer('#4A90D9');
      // Expected: R≈228, G≈239, B≈249
      const [r, g, b] = hexToRgbTest(container);
      expect(r).toBeCloseTo(228, -1); // within 5
      expect(g).toBeCloseTo(239, -1);
      expect(b).toBeCloseTo(249, -1);
    });

    it('blends white (#FFFFFF) to white', () => {
      const container = hexToContainer('#FFFFFF');
      expect(container.toLowerCase()).toBe('#ffffff');
    });
  });

  describe('hexToOnContainer — darken 40%', () => {
    it('produces a darker color than the input', () => {
      const onContainer = hexToOnContainer('#4A90D9');
      expect(onContainer).toMatch(/^#[0-9a-f]{6}$/i);
      // 40% darker: each channel * 0.6
      // #4A90D9 = rgb(74, 144, 217) → rgb(44, 86, 130) ≈ #2C5682
      const [r, g, b] = hexToRgbTest(onContainer);
      expect(r).toBeLessThan(74);
      expect(g).toBeLessThan(144);
      expect(b).toBeLessThan(217);
    });

    it('darkens #4A90D9 by 40% correctly', () => {
      const onContainer = hexToOnContainer('#4A90D9');
      const [r, g, b] = hexToRgbTest(onContainer);
      expect(r).toBeCloseTo(74 * 0.6, -1);
      expect(g).toBeCloseTo(144 * 0.6, -1);
      expect(b).toBeCloseTo(217 * 0.6, -1);
    });
  });

  describe('deriveScheduleXColors', () => {
    it('returns main unchanged', () => {
      const result = deriveScheduleXColors('#4A90D9');
      expect(result.main).toBe('#4A90D9');
    });

    it('returns container and onContainer as hex strings', () => {
      const result = deriveScheduleXColors('#4A90D9');
      expect(result.container).toMatch(/^#[0-9a-f]{6}$/i);
      expect(result.onContainer).toMatch(/^#[0-9a-f]{6}$/i);
    });

    it('container is lighter than main', () => {
      const result = deriveScheduleXColors('#4A90D9');
      const [mr, mg, mb] = hexToRgbTest(result.main);
      const [cr, cg, cb] = hexToRgbTest(result.container);
      // All container channels should be >= main channels (blending with white)
      expect(cr).toBeGreaterThanOrEqual(mr);
      expect(cg).toBeGreaterThanOrEqual(mg);
      expect(cb).toBeGreaterThanOrEqual(mb);
    });

    it('onContainer is darker than main', () => {
      const result = deriveScheduleXColors('#4A90D9');
      const [mr, mg, mb] = hexToRgbTest(result.main);
      const [or, og, ob] = hexToRgbTest(result.onContainer);
      // All onContainer channels should be <= main channels (darken)
      expect(or).toBeLessThanOrEqual(mr);
      expect(og).toBeLessThanOrEqual(mg);
      expect(ob).toBeLessThanOrEqual(mb);
    });

    it('works for the shared-family rose color', () => {
      const result = deriveScheduleXColors('#F25C7A');
      expect(result.main).toBe('#F25C7A');
      expect(result.container).toMatch(/^#[0-9a-f]{6}$/i);
      expect(result.onContainer).toMatch(/^#[0-9a-f]{6}$/i);
    });
  });
});

// ── Test helper ────────────────────────────────────────────────────────────

function hexToRgbTest(hex: string): [number, number, number] {
  const clean = hex.replace('#', '');
  return [
    parseInt(clean.slice(0, 2), 16),
    parseInt(clean.slice(2, 4), 16),
    parseInt(clean.slice(4, 6), 16),
  ];
}
