import { isNullOrUndefined } from '@coveo/bueno';
import { configuration } from '../../../app/common-reducers.js';
import { attachResult, detachResult, } from '../../../features/attached-results/attached-results-actions.js';
import { logCaseAttach, logCaseDetach, } from '../../../features/attached-results/attached-results-analytics-actions.js';
import { attachedResultsReducer as attachedResults } from '../../../features/attached-results/attached-results-slice.js';
import { buildAttachedResultFromSearchResult } from '../../../features/attached-results/attached-results-utils.js';
import { loadReducerError } from '../../../utils/errors.js';
import { buildController, } from '../../controller/headless-controller.js';
/**
 *
 * @param engine - The headless engine.
 * @param props - The configurable `AttachToCase` properties.
 * @returns - A `AttachToCase` controller instance.
 *
 * @group Controllers
 * @category AttachToCase
 */
export function buildAttachToCase(engine, props) {
    if (!loadAttachedResultsReducers(engine)) {
        throw loadReducerError;
    }
    const { dispatch } = engine;
    const getState = () => engine.state.attachedResults;
    const controller = buildController(engine);
    const { result, caseId } = props.options;
    const isResultAttached = () => {
        if (isNullOrUndefined(caseId)) {
            return false;
        }
        if (isNullOrUndefined(result.raw.permanentid) &&
            isNullOrUndefined(result.raw.urihash)) {
            return false;
        }
        return engine.state.attachedResults.results.some((attached) => {
            const caseIdMatches = caseId === attached.caseId;
            const permanentIdMatches = !isNullOrUndefined(attached.permanentId) &&
                attached.permanentId === result.raw.permanentid;
            const uriHashMatches = !isNullOrUndefined(attached.uriHash) &&
                attached.uriHash === result.raw.urihash;
            return caseIdMatches && (permanentIdMatches || uriHashMatches);
        });
    };
    return {
        ...controller,
        get state() {
            return getState();
        },
        isAttached() {
            return isResultAttached();
        },
        attach() {
            dispatch(attachResult({
                result: buildAttachedResultFromSearchResult(result, caseId),
            }));
            dispatch(logCaseAttach(result));
        },
        detach() {
            dispatch(detachResult({
                result: buildAttachedResultFromSearchResult(result, caseId),
            }));
            dispatch(logCaseDetach(result));
        },
    };
}
function loadAttachedResultsReducers(engine) {
    engine.addReducers({ configuration, attachedResults });
    return true;
}
