// (C) 2024-2026 GoodData Corporation
import { call, put, select } from "redux-saga/effects";
import { areObjRefsEqual, isDashboardAttributeFilter, } from "@gooddata/sdk-model";
import { defaultErrorHandler } from "@gooddata/sdk-ui";
import { changeFilterContextSelectionByParams, reloadFilterViews, } from "../../commands/filters.js";
import { filterViewApplicationFailed, filterViewApplicationSucceeded, filterViewCreationFailed, filterViewCreationSucceeded, filterViewDefaultStatusChangeFailed, filterViewDefaultStatusChangeSucceeded, filterViewDeletionFailed, filterViewDeletionSucceeded, } from "../../events/filters.js";
import { selectCatalogParameters } from "../../store/catalog/catalogSelectors.js";
import { selectIsApplyFiltersAllAtOnceEnabledAndSet } from "../../store/config/configSelectors.js";
import { selectCrossFilteringFiltersLocalIdentifiers } from "../../store/drill/drillSelectors.js";
import { selectFilterViews } from "../../store/filterViews/filterViewsReducersSelectors.js";
import { filterViewsActions } from "../../store/filterViews/index.js";
import { selectAttributeFilterConfigsOverrides } from "../../store/tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
import { selectFilterContextDefinition, selectWorkingFilterContextDefinition, } from "../../store/tabs/filterContext/filterContextSelectors.js";
import { tabsActions } from "../../store/tabs/index.js";
import { selectFilterViewParameters } from "../../store/tabs/parameters/parametersSelectors.js";
import { selectActiveTabLocalIdentifier } from "../../store/tabs/tabsSelectors.js";
import { loadFilterViews } from "../dashboard/initializeDashboardHandler/loadFilterViews.js";
import { resetCrossFiltering } from "./common.js";
import { resolveFilterViewParameterValues } from "./filterViewParameters.js";
function createFilterView(ctx, filterView) {
    return ctx.backend.workspace(ctx.workspace).dashboards().createFilterView(filterView);
}
export function* saveFilterViewHandler(ctx, cmd) {
    yield put(filterViewsActions.setFilterLoading(true));
    if (!ctx.dashboardRef) {
        throw Error("Dashboard ref must be provided.");
    }
    // Get active tab ID
    const activeTabLocalIdentifier = yield select(selectActiveTabLocalIdentifier);
    const appliedFilterContext = yield select(selectFilterContextDefinition);
    const workingFilterContext = yield select(selectWorkingFilterContextDefinition);
    const isApplyAllAtOnceEnabledAndSet = yield select(selectIsApplyFiltersAllAtOnceEnabledAndSet);
    const filterContext = isApplyAllAtOnceEnabledAndSet ? workingFilterContext : appliedFilterContext;
    const virtualFilters = yield select(selectCrossFilteringFiltersLocalIdentifiers);
    const sanitizedFilterContext = {
        ...filterContext,
        // accept date filters, unknown filters (will probably always be true), non-virtual filters
        filters: filterContext.filters.filter((filter) => !isDashboardAttributeFilter(filter) ||
            !filter.attributeFilter.localIdentifier ||
            !virtualFilters.includes(filter.attributeFilter.localIdentifier)),
    };
    const parameters = yield select(selectFilterViewParameters);
    const filterView = {
        name: cmd.payload.name,
        dashboard: ctx.dashboardRef,
        filterContext: sanitizedFilterContext,
        isDefault: cmd.payload.isDefault,
        // Include tabId if there's an active tab
        ...(activeTabLocalIdentifier ? { tabLocalIdentifier: activeTabLocalIdentifier } : {}),
        ...(parameters ? { parameters } : {}),
    };
    try {
        const newFilterView = yield call(createFilterView, ctx, filterView);
        yield put(reloadFilterViews());
        yield put(filterViewCreationSucceeded(ctx, newFilterView, cmd.correlationId));
    }
    catch (error) {
        defaultErrorHandler(error);
        yield put(filterViewCreationFailed(ctx));
        yield put(filterViewsActions.setFilterLoading(false));
    }
}
function deleteFilterView(ctx, ref) {
    return ctx.backend.workspace(ctx.workspace).dashboards().deleteFilterView(ref);
}
export function* deleteFilterViewHandler(ctx, cmd) {
    yield put(filterViewsActions.setFilterLoading(true));
    try {
        const filterView = yield call(findFilterView, cmd.payload.ref);
        yield call(deleteFilterView, ctx, cmd.payload.ref);
        yield put(reloadFilterViews());
        yield put(filterViewDeletionSucceeded(ctx, filterView, cmd.correlationId));
    }
    catch (error) {
        defaultErrorHandler(error);
        yield put(filterViewDeletionFailed(ctx));
        yield put(filterViewsActions.setFilterLoading(false));
    }
}
function* findFilterView(ref) {
    const filterViews = yield select(selectFilterViews);
    return filterViews.find((filterView) => areObjRefsEqual(filterView.ref, ref));
}
export function* applyFilterViewHandler(ctx, cmd) {
    const filterView = yield call(findFilterView, cmd.payload.ref);
    const attributeFilterConfigs = yield select(selectAttributeFilterConfigsOverrides);
    if (filterView) {
        yield call(resetCrossFiltering, cmd);
        const isApplyAllAtOnceEnabledAndSet = yield select(selectIsApplyFiltersAllAtOnceEnabledAndSet);
        if (isApplyAllAtOnceEnabledAndSet) {
            yield put(tabsActions.resetWorkingSelection());
        }
        yield put(changeFilterContextSelectionByParams({
            filters: filterView.filterContext.filters,
            attributeFilterConfigs,
            resetOthers: true,
            correlationId: cmd.correlationId,
        }));
        if (filterView.parameters && filterView.parameters.length > 0) {
            const workspaceParameters = yield select(selectCatalogParameters);
            const values = resolveFilterViewParameterValues(filterView.parameters, workspaceParameters);
            yield put(tabsActions.setParameterRuntimeValues({ values }));
        }
        yield put(filterViewApplicationSucceeded(ctx, filterView, cmd.correlationId));
    }
    else {
        yield put(filterViewApplicationFailed(ctx));
    }
}
function setFilterViewAsDefault(ctx, ref, isDefault) {
    return ctx.backend.workspace(ctx.workspace).dashboards().setFilterViewAsDefault(ref, isDefault);
}
export function* setFilterViewAsDefaultHandler(ctx, cmd) {
    yield put(filterViewsActions.setFilterLoading(true));
    const filterView = yield call(findFilterView, cmd.payload.ref);
    const updatedFilterView = {
        ...filterView,
        isDefault: !filterView.isDefault,
    };
    try {
        yield call(setFilterViewAsDefault, ctx, cmd.payload.ref, cmd.payload.isDefault);
        yield put(reloadFilterViews());
        yield put(filterViewDefaultStatusChangeSucceeded(ctx, updatedFilterView, cmd.correlationId));
    }
    catch (error) {
        defaultErrorHandler(error);
        yield put(filterViewDefaultStatusChangeFailed(ctx, updatedFilterView));
        yield put(filterViewsActions.setFilterLoading(false));
    }
}
export function* reloadFilterViewsHandler(ctx) {
    yield put(filterViewsActions.setFilterLoading(true));
    try {
        const filterViews = yield call(loadFilterViews, ctx);
        yield put(filterViewsActions.setFilterViews({
            dashboard: ctx.dashboardRef, // should be defined already
            filterViews,
        }));
    }
    catch (error) {
        defaultErrorHandler(error);
        yield put(filterViewsActions.setFilterLoading(false));
    }
}
