/**
 * BrandStrategyPipeline — brand-core completeness check for `brandPromise`
 *
 * `brandPromise` is part of the brand-core JSON schema and is a headline field in
 * the UI (Brand Manual hero/cover, Brand Strategy section, PDF export), but it was
 * the one brand-core content field with no completeness check. When the model
 * omitted it, nothing flagged it and no enhancement pass ran, so the strategy was
 * saved with an empty promise while brandName/tagline came through — leaving the
 * Brand Manual hero with a name and tagline but no promise to render (TC_376).
 *
 * These pin that a missing brandPromise triggers the existing enhancement retry and
 * that the recovered value lands in the pipeline analysis.
 */

import { generateWithAI } from '../../../utils/aiProvider';
import { BrandStrategyPipeline } from '../brandStrategyPipeline';
import type { BrandStrategyPipelineInputs } from '../brandStrategyPrompts';

jest.mock('../../../utils/aiProvider', () => ({
  generateWithAI: jest.fn(),
}));

const mockedGenerateWithAI = generateWithAI as jest.MockedFunction<typeof generateWithAI>;

const INPUTS = { companyName: 'Sweet Co' } as unknown as BrandStrategyPipelineInputs;

const PROMISE_TEXT =
  'We guarantee pure, authentic sweetness in every bite and sip, blending traditional ' +
  'flavors with innovative, guilt-free craftsmanship that brings joy to you';

function aiResponse(payload: Record<string, unknown>) {
  return {
    content: JSON.stringify(payload),
    provider: 'test',
    model: 'test-model',
    tokenUsage: { totalTokens: 0, inputTokens: 0, outputTokens: 0 },
  } as unknown as Awaited<ReturnType<typeof generateWithAI>>;
}

/** brand-core reply missing brandPromise, then the remaining stages. */
function queueRun(coreReply: Record<string, unknown>, enhancementReply?: Record<string, unknown>) {
  mockedGenerateWithAI.mockResolvedValueOnce(aiResponse(coreReply));
  if (enhancementReply) {
    mockedGenerateWithAI.mockResolvedValueOnce(aiResponse(enhancementReply));
  }
  // Stage 2 and stage 3 — enough to satisfy their own completeness checks.
  mockedGenerateWithAI.mockResolvedValueOnce(
    aiResponse({ brandPositioning: 'Positioning', brandPersonality: ['caring'] })
  );
  mockedGenerateWithAI.mockResolvedValueOnce(
    aiResponse({
      brandMessage: 'Message',
      elevatorPitch: 'Pitch',
      mascots: 'Mascot',
      jingles: 'Jingle',
      punchlines: 'Punchline',
    })
  );
}

describe('BrandStrategyPipeline — brand-core brandPromise completeness', () => {
  beforeEach(() => {
    mockedGenerateWithAI.mockReset();
  });

  it('flags a missing brandPromise and recovers it via the enhancement pass', async () => {
    queueRun(
      { brandName: 'Sweet Co', tagline: 'Pure joy', brandArchetype: 'Caregiver' },
      { brandPromise: PROMISE_TEXT }
    );

    const result = await new BrandStrategyPipeline(INPUTS).run();

    const enhancement = result.stageResults.find(s => s.stage === 'brand-core-enhancement');
    expect(enhancement?.success).toBe(true);

    // The enhancement prompt must name brandPromise as the field to improve.
    const enhancementCall = mockedGenerateWithAI.mock.calls[1];
    expect(enhancementCall[0]).toContain('brandPromise');

    expect(result.analysis.brandPromise).toBe(PROMISE_TEXT);
    // The fields brand-core already produced are preserved.
    expect(result.analysis.brandName).toBe('Sweet Co');
    expect(result.analysis.tagline).toBe('Pure joy');
  });

  it('treats an empty-string brandPromise as missing', async () => {
    queueRun(
      { brandName: 'Sweet Co', tagline: 'Pure joy', brandArchetype: 'Caregiver', brandPromise: '' },
      { brandPromise: PROMISE_TEXT }
    );

    const result = await new BrandStrategyPipeline(INPUTS).run();

    expect(result.stageResults.some(s => s.stage === 'brand-core-enhancement')).toBe(true);
    expect(result.analysis.brandPromise).toBe(PROMISE_TEXT);
  });

  it('does not run an enhancement pass when brand-core is already complete', async () => {
    queueRun({
      brandName: 'Sweet Co',
      tagline: 'Pure joy',
      brandArchetype: 'Caregiver',
      brandPromise: PROMISE_TEXT,
    });

    const result = await new BrandStrategyPipeline(INPUTS).run();

    expect(result.stageResults.some(s => s.stage.endsWith('-enhancement'))).toBe(false);
    expect(result.analysis.brandPromise).toBe(PROMISE_TEXT);
  });
});
