// Wave 2B — OFFSEASON HUB · FuturesBoard. Source + helper asserts. Futures are
// TRACKED, NOT GRADED — the board carries that label, never renders a grade,
// self-hides on an empty feed, and colors movement per the contract
// (shortening→green / drifting→amber / flat→dim) — NEVER red for a drift.

const fs = require('fs');
const path = require('path');
const WEB = path.join(__dirname, '..', '..', 'web', 'src');
const src = fs.readFileSync(path.join(WEB, 'components', 'vyndr', 'FuturesBoard.tsx'), 'utf8');
const { moveColor, moveLabel, MOVE_COLOR } = require('../../web/src/lib/futuresMove');

describe('futuresMove — the color contract (never red)', () => {
  it('shortening → green (toward the selection)', () => {
    expect(moveColor('shortening')).toBe('var(--g-a)');
  });
  it('drifting → amber (caution, NOT a miss)', () => {
    expect(moveColor('drifting')).toBe('var(--amber)');
  });
  it('flat / absent / unknown → dim (say less)', () => {
    expect(moveColor('flat')).toBe('var(--text-2)');
    expect(moveColor(undefined)).toBe('var(--text-2)');
    expect(moveColor('sideways')).toBe('var(--text-2)');
  });
  it('NO move ever renders red (--miss reserved for settled-negative)', () => {
    Object.values(MOVE_COLOR).forEach((v) => expect(v).not.toMatch(/miss/));
    ['shortening', 'drifting', 'flat', undefined, 'x'].forEach((m) =>
      expect(moveColor(m)).not.toMatch(/miss/)
    );
  });
  it('moveLabel is empty when there is no move (never fabricated)', () => {
    expect(moveLabel(undefined)).toBe('');
    expect(moveLabel('shortening')).toMatch(/SHORTENING/);
  });
});

describe('FuturesBoard.tsx source', () => {
  it('fetches the REAL futures endpoint', () => {
    expect(src).toMatch(/\/api\/futures\//);
  });

  it('carries the honest "TRACKED · NOT GRADED" label', () => {
    expect(src).toContain('TRACKED · NOT GRADED');
  });

  it('NEVER renders a grade on a future (no GradeBadge)', () => {
    expect(src).not.toContain('GradeBadge');
    expect(src).not.toMatch(/import.*GradeBadge/);
  });

  it('SELF-HIDES when there are no markets (returns null)', () => {
    expect(src).toMatch(/return null/);
    expect(src).toMatch(/list\.length === 0/);
  });

  it('renders real markets + selections with mono tabular prices', () => {
    expect(src).toMatch(/list\.map/);
    expect(src).toMatch(/selections/);
    expect(src).toContain('className="mono"');
    expect(src).toContain('tabular-nums');
  });

  it('shows a move ONLY when the backend supplied one, via the contract color', () => {
    expect(src).toContain('moveColor');
    expect(src).toContain('moveLabel');
    // movement is gated on a truthy label (never fabricated)
    expect(src).toMatch(/label &&/);
  });

  it('data surface carries NO glitch classes', () => {
    expect(src).not.toMatch(/wm-tear|glitch-shift|head-tear|glitch-hover/);
  });
});

describe('ExploreHub mounts FuturesBoard', () => {
  const hub = fs.readFileSync(path.join(WEB, 'components', 'ExploreHub.tsx'), 'utf8');
  it('imports + mounts <FuturesBoard sport=', () => {
    expect(hub).toMatch(/import FuturesBoard from '@\/components\/vyndr\/FuturesBoard'/);
    expect(hub).toMatch(/<FuturesBoard sport=\{sport\}/);
  });
});
