import { createAnswerRunner } from '../../../api/knowledge/answer-generation/agents/answer-agent/answer-agent-runner.js';
import { createFollowUpAgent } from '../../../api/knowledge/answer-generation/agents/follow-up-agent/follow-up-agent.js';
import { createFollowUpStrategy } from '../../../api/knowledge/answer-generation/agents/follow-up-agent/follow-up-answer-strategy.js';
import { setAgentId } from '../../../features/configuration/configuration-actions.js';
import { selectAccessToken, selectEnvironment, selectOrganizationId, } from '../../../features/configuration/configuration-selectors.js';
import { activeFollowUpStartFailed, createFollowUpAnswer, dislikeFollowUp, likeFollowUp, } from '../../../features/follow-up-answers/follow-up-answers-actions.js';
import { followUpAnswersReducer as followUpAnswers } from '../../../features/follow-up-answers/follow-up-answers-slice.js';
import { loadReducerError } from '../../../utils/errors.js';
import { buildCoreGeneratedAnswer, } from '../../core/generated-answer/headless-core-generated-answer.js';
/**
 *
 * @internal
 *
 * Creates a `GeneratedAnswerWithFollowUps` controller instance using the Answer API stream pattern.
 *
 * @param engine - The headless engine.
 * @param props - The configurable `GeneratedAnswerWithFollowUps` properties.
 * @returns A `GeneratedAnswerWithFollowUps` controller instance.
 */
export function buildGeneratedAnswerWithFollowUps(engine, analyticsClient, props) {
    if (!props.agentId || props.agentId.trim() === '') {
        throw new Error('agentId is required for GeneratedAnswerWithFollowUps');
    }
    if (!loadReducers(engine)) {
        throw loadReducerError;
    }
    const { ...controller } = buildCoreGeneratedAnswer(engine, analyticsClient, props);
    const getState = () => engine.state;
    engine.dispatch(setAgentId(props.agentId));
    const organizationId = selectOrganizationId(getState());
    const accessToken = selectAccessToken(getState());
    const environment = selectEnvironment(getState());
    const followUpAgent = createFollowUpAgent(props.agentId, organizationId, environment);
    const followUpStrategy = createFollowUpStrategy(engine.dispatch);
    const answerRunner = createAnswerRunner();
    return {
        ...controller,
        get state() {
            const followUpAnswersState = getState().followUpAnswers;
            return {
                ...getState().generatedAnswer,
                followUpAnswers: followUpAnswersState,
            };
        },
        retry() {
            answerRunner.run(engine.state, engine.dispatch, () => engine.navigatorContext);
        },
        // TODO: SFINT-6665
        like(answerId) {
            if (!answerId || this.state.answerId === answerId) {
                controller.like();
                return;
            }
            if (!this.state.liked) {
                engine.dispatch(likeFollowUp({ answerId }));
                engine.dispatch(analyticsClient.logLikeGeneratedAnswer(answerId));
            }
        },
        // TODO: SFINT-6665
        dislike(answerId) {
            if (!answerId || this.state.answerId === answerId) {
                controller.dislike();
                return;
            }
            if (!this.state.disliked) {
                engine.dispatch(dislikeFollowUp({ answerId }));
                engine.dispatch(analyticsClient.logDislikeGeneratedAnswer(answerId));
            }
        },
        // TODO: SFINT-6665
        logCopyToClipboard(answerId) {
            if (!answerId || this.state.answerId === answerId) {
                controller.logCopyToClipboard();
                return;
            }
            engine.dispatch(analyticsClient.logCopyGeneratedAnswer(answerId));
        },
        // TODO: SFINT-6665
        logCitationClick(citationId, answerId) {
            if (!answerId || this.state.answerId === answerId) {
                controller.logCitationClick(citationId);
                return;
            }
            engine.dispatch(analyticsClient.logOpenGeneratedAnswerSource(citationId, answerId));
        },
        // TODO: SFINT-6665
        logCitationHover(citationId, citationHoverTimeMs, answerId) {
            if (!answerId || this.state.answerId === answerId) {
                controller.logCitationHover(citationId, citationHoverTimeMs);
                return;
            }
            engine.dispatch(analyticsClient.logHoverCitation(citationId, citationHoverTimeMs, answerId));
        },
        async askFollowUp(question) {
            if (!question || question.trim() === '') {
                return;
            }
            const conversationId = this.state.followUpAnswers.conversationId;
            if (!conversationId) {
                console.warn('Missing conversationId when generating a follow-up answer. ' +
                    'The generateFollowUpAnswer action requires an existing conversation.');
                return;
            }
            followUpAgent.abortRun();
            engine.dispatch(createFollowUpAnswer({ question }));
            try {
                await followUpAgent.runAgent({
                    forwardedProps: {
                        q: question,
                        conversationId,
                        accessToken,
                    },
                }, followUpStrategy);
            }
            catch (error) {
                engine.dispatch(activeFollowUpStartFailed({
                    message: 'An error occurred while starting the follow-up answer generation.',
                }));
                console.error('Error running the follow-up agent:', error);
            }
        },
    };
}
function loadReducers(engine) {
    engine.addReducers({
        followUpAnswers,
    });
    return true;
}
