import { a as KlevuConfig, p as post } from './klevu-init2.js';

var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
const STORAGE_KEY = "klevu-moi-session";
function startMoi(options = {}) {
    var _a, _b, _c;
    return __awaiter(this, void 0, void 0, function* () {
        const config = ((_a = options.settings) === null || _a === void 0 ? void 0 : _a.configOverride) || KlevuConfig.getDefault();
        let startingMessages = [];
        let ctx = {
            klevuApiKey: config.apiKey,
            sessionId: "",
            mode: options.mode,
            url: options.url,
            productId: options.productId,
            pqaWidgetId: options.pqaWidgetId,
        };
        const storedSession = yield getStoredSession();
        let menu;
        let genericOptions;
        let feedbacks = [];
        let shouldSendMessage = false;
        const PQAKey = options.productId || options.url;
        if (storedSession && storedSession.context) {
            switch (options.mode) {
                case undefined:
                    ctx.sessionId = storedSession.context.sessionId;
                    if (storedSession.MOI) {
                        startingMessages = storedSession.MOI.messages;
                        menu = storedSession.MOI.menu;
                        genericOptions = storedSession.MOI.genericOptions;
                        feedbacks = storedSession.MOI.feedbacks;
                        if ((_b = options.settings) === null || _b === void 0 ? void 0 : _b.alwaysStartConversation) {
                            shouldSendMessage = storedSession.MOI.messages.length === 0;
                        }
                    }
                    break;
                case "PQA":
                    ctx.sessionId = storedSession.context.sessionId;
                    if (PQAKey && storedSession.PQA && storedSession.PQA[PQAKey]) {
                        startingMessages = storedSession.PQA[PQAKey].messages;
                        menu = storedSession.PQA[PQAKey].menu;
                        genericOptions = storedSession.PQA[PQAKey].genericOptions;
                        feedbacks = storedSession.PQA[PQAKey].feedbacks;
                        if ((_c = options.settings) === null || _c === void 0 ? void 0 : _c.alwaysStartConversation) {
                            shouldSendMessage = storedSession.PQA[PQAKey].messages.length === 0;
                        }
                    }
            }
        }
        else {
            shouldSendMessage = true;
        }
        if (shouldSendMessage) {
            const result = yield queryMoi({
                context: ctx,
            }, config);
            if (!(result === null || result === void 0 ? void 0 : result.data[0].context)) {
                throw new Error("No context found");
            }
            const parsed = parseResponse(result);
            ctx = parsed.context;
            startingMessages = parsed.messages;
            menu = parsed.menu;
            genericOptions = parsed.genericOptions;
        }
        return new MoiSession({
            feedbacks,
            messages: startingMessages,
            menu,
            genericOptions,
        }, options, ctx, config);
    });
}
class MoiSession {
    constructor(state, options, context, config) {
        var _a;
        this.messages = state.messages;
        this.menu = state.menu;
        this.genericOptions = state.genericOptions;
        this.feedbacks = (_a = state.feedbacks) !== null && _a !== void 0 ? _a : [];
        this.options = options;
        this.context = context;
        this.config = config;
        if (this.context.url && this.context.productId) {
            throw new Error("Cannot set both url and productId for PQA");
        }
        this.save();
    }
    query(request, target) {
        var _a, _b, _c, _d, _e, _f, _g;
        return __awaiter(this, void 0, void 0, function* () {
            if (request.message) {
                this.messages = [
                    ...((_a = this.messages) !== null && _a !== void 0 ? _a : []),
                    { local: { message: request.message } },
                ];
                (_c = (_b = this.options).onMessage) === null || _c === void 0 ? void 0 : _c.call(_b);
            }
            const res = yield queryMoi(Object.assign({ context: this.context }, request), this.config, target);
            if (!res) {
                throw new Error("No response from MOI");
            }
            // run actions first
            for (const obj of res.data) {
                if ("actions" in obj) {
                    for (const action of obj.actions.actions) {
                        //notify listeners if they want to do something
                        const response = (_e = (_d = this.options).onAction) === null || _e === void 0 ? void 0 : _e.call(_d, action);
                        // allow listeners to cancel the default actions
                        if (response === false) {
                            continue;
                        }
                        if (action.type === "purgeHistory") {
                            this.clear();
                        }
                        else if (action.type === "redirectToUrl" && action.context.link) {
                            if (this.options.onRedirect) {
                                this.options.onRedirect(action.context.link);
                            }
                            else {
                                window.location.href = action.context.link;
                            }
                        }
                    }
                }
            }
            const { messages, genericOptions, menu, context } = parseResponse(res);
            this.messages = [...this.messages, ...messages];
            (_g = (_f = this.options).onMessage) === null || _g === void 0 ? void 0 : _g.call(_f);
            this.genericOptions = genericOptions;
            this.menu = menu;
            this.context = context;
            this.save();
            return res;
        });
    }
    clear() {
        var _a, _b;
        this.messages = [];
        this.feedbacks = [];
        this.save();
        (_b = (_a = this.options).onMessage) === null || _b === void 0 ? void 0 : _b.call(_a);
    }
    save() {
        const PQAkey = this.context.productId || this.context.url;
        switch (this.context.mode) {
            case undefined:
                saveSession({
                    context: this.context,
                    MOI: {
                        menu: this.menu,
                        genericOptions: this.genericOptions,
                        messages: this.messages,
                        feedbacks: this.feedbacks,
                    },
                });
                break;
            case "PQA":
                if (!PQAkey) {
                    throw new Error("Cannot save PQA session without url or productId");
                }
                saveSession({
                    context: this.context,
                    PQA: {
                        [PQAkey]: {
                            menu: this.menu,
                            genericOptions: this.genericOptions,
                            messages: this.messages,
                            feedbacks: this.feedbacks,
                        },
                    },
                });
        }
    }
    addFeedback(messageId, thumbs, reason) {
        return __awaiter(this, void 0, void 0, function* () {
            const oldFeedback = this.feedbacks.find((f) => f.id === messageId);
            if (oldFeedback) {
                oldFeedback.thumbs = thumbs;
                oldFeedback.reason = reason;
            }
            else {
                this.feedbacks.push({ id: messageId, thumbs, reason });
            }
            return this.query({
                feedback: {
                    messageId,
                    thumbs: thumbs.toUpperCase(),
                    reason,
                },
            }, "feedback");
        });
    }
}
function getStoredSession() {
    const storedSession = localStorage.getItem(STORAGE_KEY);
    if (!storedSession) {
        return undefined;
    }
    return JSON.parse(storedSession);
}
function saveSession(session) {
    const saved = localStorage.getItem(STORAGE_KEY);
    let parsed = {};
    if (saved) {
        parsed = JSON.parse(saved);
    }
    const key = session.context.productId || session.context.url;
    switch (session.context.mode) {
        case undefined:
            parsed.context = session.context;
            parsed.MOI = session.MOI;
            break;
        case "PQA":
            parsed.context = session.context;
            if (!parsed.PQA) {
                parsed.PQA = {};
            }
            if (!key || !session.PQA) {
                throw new Error("No url, productId or PQA session");
            }
            parsed.PQA[key] = session.PQA[key];
            break;
    }
    localStorage.setItem(STORAGE_KEY, JSON.stringify(parsed));
}
function queryMoi(request, config, target = "send") {
    return __awaiter(this, void 0, void 0, function* () {
        return yield post(`${config.moiApiUrl}chat/${target}`, request);
    });
}
function parseResponse(response) {
    const messages = [];
    let genericOptions = undefined;
    let menu = undefined;
    const context = response.data[0].context;
    for (const d of response.data) {
        "message" in d && messages.push(d);
        "filter" in d && messages.push(d);
        "productData" in d && messages.push(d);
        if ("genericOptions" in d) {
            genericOptions = d.genericOptions;
        }
        if ("menuOptions" in d) {
            menu = d.menuOptions;
        }
    }
    return {
        context,
        messages,
        menu,
        genericOptions,
    };
}

export { startMoi as s };

//# sourceMappingURL=moi.js.map