/**
 * MockLLMClient 자체의 sanity test.
 *
 * 이게 통과하면 dispatcher / ceoPlanner / ChunkedWriter 등 IAIService 를 받는
 * 코드가 *실제 LLM 없이* 단위 / integration 테스트 가능.
 *
 * 향후 dispatcher 의 multi-stage flow 같은 큰 integration 테스트는 이 mock 을
 * 주입해서 실제 fetch 없이 검증.
 */
import { MockLLMClient } from '../helpers/mockLLMClient';

describe('MockLLMClient', () => {
    test('큐된 응답을 순차적으로 소비한다', async () => {
        const ai = new MockLLMClient();
        ai.setNextResponse('first');
        ai.setNextResponse('second');

        const r1 = await ai.chat({ user: 'a' });
        const r2 = await ai.chat({ user: 'b' });

        expect(r1.content).toBe('first');
        expect(r2.content).toBe('second');
        expect(ai.calls).toHaveLength(2);
        expect(ai.calls[0].user).toBe('a');
        expect(ai.calls[1].user).toBe('b');
    });

    test('큐가 비면 responder 함수로 동적 응답', async () => {
        const ai = new MockLLMClient();
        ai.setResponder((req) =>
            req.user.includes('summary') ? '요약 결과' : '일반 답변',
        );

        const r1 = await ai.chat({ user: 'give me summary' });
        const r2 = await ai.chat({ user: 'hello' });

        expect(r1.content).toBe('요약 결과');
        expect(r2.content).toBe('일반 답변');
    });

    test('큐가 responder 보다 우선', async () => {
        const ai = new MockLLMClient();
        ai.setResponder(() => 'from responder');
        ai.setNextResponse('from queue');

        const r1 = await ai.chat({ user: 'x' });
        const r2 = await ai.chat({ user: 'y' });

        expect(r1.content).toBe('from queue');
        expect(r2.content).toBe('from responder');
    });

    test('signal 이 이미 abort 된 상태면 AbortError 던진다', async () => {
        const ai = new MockLLMClient();
        const ctrl = new AbortController();
        ctrl.abort();

        await expect(ai.chat({ user: 'x', signal: ctrl.signal })).rejects.toThrow(/AbortError/);
        // 호출은 기록됨 (signalAborted: true).
        expect(ai.calls).toHaveLength(1);
        expect(ai.calls[0].signalAborted).toBe(true);
    });

    test('legacy call(prompt) 도 동작', async () => {
        const ai = new MockLLMClient();
        ai.setNextResponse('plain');

        const result = await ai.call('hi');

        expect(result).toBe('plain');
        expect(ai.calls).toHaveLength(1);
    });

    test('reset() 으로 상태 초기화', async () => {
        const ai = new MockLLMClient();
        ai.setNextResponse('x');
        await ai.chat({ user: 'a' });

        ai.reset();

        expect(ai.calls).toHaveLength(0);
        // 큐도 비었으니 기본 fallback 응답.
        const r = await ai.chat({ user: 'b' });
        expect(r.content).toContain('mock response');
    });
});
