import { describe, it, expect } from 'vitest';
import { buildBaseSystemPrompt } from '@/lib/ai/systemPromptBase';

/**
 * The base system prompt is the structural contract every template
 * inherits. These tests pin the *invariants* that must always hold:
 *  - JSON-only output rule
 *  - "use library exerciseIds" rule (fixes the bug where the model
 *    invented ids and apply blew up)
 *  - "suggested weight is required" rule
 *  - The conditional history-vs-no-history block toggles correctly
 *  - The local-model nudge appears for Ollama
 *
 * Wording can shift over time; these assertions check substrings, not
 * exact matches, so coaching tone changes don't break tests.
 */

describe('buildBaseSystemPrompt', () => {
  it('always demands JSON-only output (no fences)', () => {
    const p = buildBaseSystemPrompt({
      weightUnit: 'lbs',
      hasHistoryContext: false,
      isLocalModel: false,
    });
    expect(p).toMatch(/JSON object/i);
    expect(p).toMatch(/no.+fences/i);
  });

  it('forces use of library exerciseIds', () => {
    const p = buildBaseSystemPrompt({
      weightUnit: 'lbs',
      hasHistoryContext: false,
      isLocalModel: false,
    });
    expect(p).toMatch(/exerciseId/);
    expect(p).toMatch(/library/i);
    expect(p).toMatch(/never invent ids/i);
  });

  it('requires suggestedWeight in the user’s preferred unit', () => {
    const lbsPrompt = buildBaseSystemPrompt({
      weightUnit: 'lbs',
      hasHistoryContext: false,
      isLocalModel: false,
    });
    expect(lbsPrompt).toMatch(/suggestedWeight/);
    expect(lbsPrompt).toMatch(/lbs/);

    const kgPrompt = buildBaseSystemPrompt({
      weightUnit: 'kg',
      hasHistoryContext: false,
      isLocalModel: false,
    });
    expect(kgPrompt).toMatch(/kg/);
  });

  it('switches to "use the history block" instructions when history is present', () => {
    const withHistory = buildBaseSystemPrompt({
      weightUnit: 'lbs',
      hasHistoryContext: true,
      isLocalModel: false,
    });
    expect(withHistory).toMatch(/HISTORY block/);
    expect(withHistory).toMatch(/STAGNANT/);
  });

  it('switches to conservative-defaults instructions when no history', () => {
    const noHistory = buildBaseSystemPrompt({
      weightUnit: 'lbs',
      hasHistoryContext: false,
      isLocalModel: false,
    });
    expect(noHistory).toMatch(/WEIGHT GUIDANCE WITHOUT HISTORY/);
    expect(noHistory).toMatch(/50-65%/);
  });

  it('adds a "local model" reminder for Ollama', () => {
    const local = buildBaseSystemPrompt({
      weightUnit: 'lbs',
      hasHistoryContext: false,
      isLocalModel: true,
    });
    expect(local).toMatch(/LOCAL MODEL/);
    expect(local).toMatch(/JSON only/i);
  });

  it('omits the local-model reminder for cloud providers', () => {
    const cloud = buildBaseSystemPrompt({
      weightUnit: 'lbs',
      hasHistoryContext: true,
      isLocalModel: false,
    });
    expect(cloud).not.toMatch(/LOCAL MODEL REMINDER/);
  });
});
