// (C) 2021-2026 GoodData Corporation
import { batchActions } from "redux-batched-actions";
import { call, put, select } from "redux-saga/effects";
import { invariant } from "ts-invariant";
import { areObjRefsEqual, insightTitle, isVisualizationSwitcherWidget, serializeObjRef, widgetTitle, } from "@gooddata/sdk-model";
import { getSizeInfo } from "../../../_staging/layout/sizing.js";
import { invalidArgumentsProvided } from "../../events/general.js";
import { insightWidgetInsightChanged, } from "../../events/insight.js";
import { selectSettings } from "../../store/config/configSelectors.js";
import { insightsActions } from "../../store/insights/index.js";
import { selectInsightByRef } from "../../store/insights/insightsSelectors.js";
import { tabsActions } from "../../store/tabs/index.js";
import { selectWidgetByRef, selectWidgets, selectWidgetsMap, } from "../../store/tabs/layout/layoutSelectors.js";
import { uiActions } from "../../store/ui/index.js";
import { shouldRevalidateDrillsAfterInsightChange } from "../common/drillRevalidationUtils.js";
import { validateDrills } from "../common/validateDrills.js";
import { loadInsight } from "./common/loadInsight.js";
import { validateExistingInsightWidget } from "./validation/widgetValidations.js";
export function* changeInsightWidgetInsightHandler(ctx, cmd) {
    const { payload: { ref, insightRef, visualizationProperties }, correlationId, } = cmd;
    const widgetsMap = yield select(selectWidgetsMap);
    const widgets = yield select(selectWidgets);
    const settings = yield select(selectSettings);
    // Find if changed insight is part of Vis. Switcher
    let visSwitcherRef;
    widgets.forEach((widget) => {
        if (isVisualizationSwitcherWidget(widget)) {
            const isInsightPartOfVisSwitcher = widget.visualizations.find((visualization) => {
                return (areObjRefsEqual(visualization.ref, ref) ||
                    areObjRefsEqual(visualization.insight, insightRef));
            });
            if (isInsightPartOfVisSwitcher) {
                visSwitcherRef = widget.ref;
            }
        }
    });
    const insightWidget = validateExistingInsightWidget(widgetsMap, cmd, ctx);
    const originalInsight = yield select(selectInsightByRef(insightWidget.insight));
    invariant(originalInsight, "inconsistent store, original insight not already in store");
    const originalInsightTitle = insightTitle(originalInsight);
    // always load the insight in case it changed since we loaded the insight list
    let insight;
    try {
        insight = (yield call(loadInsight, ctx, insightRef));
    }
    catch {
        throw invalidArgumentsProvided(ctx, cmd, `The insight with ref: ${serializeObjRef(insightRef)} was not found.`);
    }
    const hasCustomName = widgetTitle(insightWidget) !== originalInsightTitle;
    const isTitleDifferent = insightTitle(insight) !== originalInsightTitle;
    const shouldChangeTitle = !hasCustomName && isTitleDifferent;
    const newSize = getSizeInfo(settings, "insight", insight);
    yield put(batchActions([
        // upsert the internal insight list
        insightsActions.upsertInsight(insight),
        // refresh the visual insight list
        uiActions.requestInsightListUpdate(),
        /**
         * Change the widget:
         * - insight
         * - properties if set
         * - title if appropriate
         */
        tabsActions.replaceInsightWidgetInsight({
            ref,
            insightRef,
            properties: visualizationProperties,
            header: shouldChangeTitle
                ? {
                    title: insightTitle(insight),
                }
                : undefined,
            newSize,
            undo: {
                cmd,
            },
        }),
    ]));
    // Run insight filter ref sanitization.
    // This is the only place where we still have both the old and new insight state.
    if (shouldRevalidateDrillsAfterInsightChange(originalInsight, insight)) {
        const updatedWidget = yield select(selectWidgetByRef(insightWidget.ref));
        yield call(validateDrills, ctx, cmd, [updatedWidget]);
    }
    // Resize Vis. Switcher
    if (visSwitcherRef) {
        yield put(tabsActions.resizeVisualizationSwitcherOnInsightChanged({
            ref: visSwitcherRef,
            newSize,
            undo: {
                cmd,
            },
        }));
    }
    return insightWidgetInsightChanged(ctx, ref, insight, correlationId);
}
