const { applyTierGating, __internals } = require('../../src/utils/tierGating');

function sampleResult(overrides = {}) {
  return {
    player: 'Jalen Brunson',
    stat_type: 'points',
    line: 26.5,
    direction: 'over',
    book: 'draftkings',
    grade: 'A',
    confidence: 78,
    edge_pct: 6.2,
    kill_conditions_triggered: [
      { code: 'TRAP', reason: 'Multiple trap signals firing.' },
      { code: 'COLD_L5', reason: 'Last-5 average below the line.' },
    ],
    reasoning: {
      summary: 'Brunson averaging 28.4 last 5; weak NYK defense; rested.',
      steps: { season_avg: { value: 26.1 }, final_grade: 'A' },
    },
    ...overrides,
  };
}

describe('applyTierGating — free tier locks the explanation surface', () => {
  test('keeps grade + confidence + edge_pct (the hook)', () => {
    const gated = applyTierGating(sampleResult(), 'free');
    expect(gated.grade).toBe('A');
    expect(gated.confidence).toBe(78);
    expect(gated.edge_pct).toBe(6.2);
    expect(gated.player).toBe('Jalen Brunson');
    expect(gated.stat_type).toBe('points');
    expect(gated.line).toBe(26.5);
    expect(gated.direction).toBe('over');
  });

  test('redacts reasoning.summary + steps + marks locked', () => {
    const gated = applyTierGating(sampleResult(), 'free');
    expect(gated.reasoning.summary).toBe(__internals.LOCKED_REASONING_SUMMARY);
    expect(gated.reasoning.steps).toBeNull();
    expect(gated.reasoning.locked).toBe(true);
  });

  test('redacts kill condition reasons but keeps codes for badge rendering', () => {
    const gated = applyTierGating(sampleResult(), 'free');
    expect(gated.kill_conditions_triggered).toHaveLength(2);
    for (const kc of gated.kill_conditions_triggered) {
      expect(kc.code).toBeDefined();
      expect(kc.reason).toBe(__internals.LOCKED_KILL_REASON);
      expect(kc.locked).toBe(true);
    }
  });

  test('tags response with tier_gated + upgrade_hint', () => {
    const gated = applyTierGating(sampleResult(), 'free');
    expect(gated.tier_gated).toBe(true);
    expect(typeof gated.upgrade_hint).toBe('string');
  });

  test('does not mutate the input result', () => {
    const original = sampleResult();
    applyTierGating(original, 'free');
    expect(original.reasoning.summary).toContain('Brunson averaging');
    expect(original.kill_conditions_triggered[0].reason).toContain('Multiple trap');
  });
});

describe('applyTierGating — paid tiers pass through unchanged', () => {
  test('analyst sees full reasoning', () => {
    const r = sampleResult();
    const out = applyTierGating(r, 'analyst');
    expect(out.reasoning.summary).toContain('Brunson averaging');
    expect(out.reasoning.locked).toBeUndefined();
    expect(out.tier_gated).toBeUndefined();
    expect(out.kill_conditions_triggered[0].reason).toContain('Multiple trap');
  });

  test('desk sees full reasoning', () => {
    const out = applyTierGating(sampleResult(), 'desk');
    expect(out.reasoning.summary).toContain('Brunson averaging');
    expect(out.tier_gated).toBeUndefined();
  });
});

describe('applyTierGating — edge cases', () => {
  test('null result returns null', () => {
    expect(applyTierGating(null, 'free')).toBeNull();
    expect(applyTierGating(undefined, 'free')).toBeUndefined();
  });

  test('unknown tier name → treated as free', () => {
    const out = applyTierGating(sampleResult(), 'pirate');
    expect(out.reasoning.locked).toBe(true);
  });

  test('result with no kill_conditions_triggered still produces a clean response', () => {
    const noKills = { ...sampleResult(), kill_conditions_triggered: [] };
    const out = applyTierGating(noKills, 'free');
    expect(out.kill_conditions_triggered).toEqual([]);
    expect(out.reasoning.locked).toBe(true);
  });

  test('result with malformed reasoning still produces a locked placeholder', () => {
    const out = applyTierGating({ ...sampleResult(), reasoning: null }, 'free');
    expect(out.reasoning.summary).toBe(__internals.LOCKED_REASONING_SUMMARY);
    expect(out.reasoning.locked).toBe(true);
  });
});
