/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/* eslint-disable no-param-reassign */
// <- When we work with Immer, we need reassign, so disabling lint
import produce from 'immer';
import { DataMask, FeatureFlag } from '@superset-ui/core';
import { NATIVE_FILTER_PREFIX } from 'src/dashboard/components/nativeFilters/FiltersConfigModal/utils';
import { HYDRATE_DASHBOARD } from 'src/dashboard/actions/hydrate';
import { isFeatureEnabled } from 'src/featureFlags';
import { getUrlParam } from 'src/utils/urlUtils';
import { URL_PARAMS } from 'src/constants';
import { DataMaskStateWithId, DataMaskWithId } from './types';
import {
  AnyDataMaskAction,
  SET_DATA_MASK_FOR_FILTER_CONFIG_COMPLETE,
  UPDATE_DATA_MASK,
} from './actions';
import {
  Filter,
  FilterConfiguration,
} from '../dashboard/components/nativeFilters/types';
import { areObjectsEqual } from '../reduxUtils';
import { Filters } from '../dashboard/reducers/types';

export function getInitialDataMask(
  id?: string | number,
  moreProps?: DataMask,
): DataMask;
export function getInitialDataMask(
  id: string | number,
  moreProps: DataMask = {},
): DataMaskWithId {
  let otherProps = {};
  if (id) {
    otherProps = {
      id,
    };
  }
  return {
    ...otherProps,
    extraFormData: {},
    filterState: {
      value: undefined,
    },
    ownState: {},
    ...moreProps,
  } as DataMaskWithId;
}

function fillNativeFilters(
  filterConfig: FilterConfiguration,
  mergedDataMask: DataMaskStateWithId,
  draftDataMask: DataMaskStateWithId,
  currentFilters?: Filters,
) {
  const dataMaskFromUrl = getUrlParam(URL_PARAMS.nativeFilters) || {};
  filterConfig.forEach((filter: Filter) => {
    mergedDataMask[filter.id] = {
      ...getInitialDataMask(filter.id), // take initial data
      ...filter.defaultDataMask, // if something new came from BE - take it
      ...dataMaskFromUrl[filter.id],
    };
    if (
      currentFilters &&
      !areObjectsEqual(
        filter.defaultDataMask,
        currentFilters[filter.id]?.defaultDataMask,
        { ignoreUndefined: true },
      )
    ) {
      mergedDataMask[filter.id] = {
        ...mergedDataMask[filter.id],
        ...filter.defaultDataMask,
      };
    }
  });

  // Get back all other non-native filters
  Object.values(draftDataMask).forEach(filter => {
    if (!String(filter?.id).startsWith(NATIVE_FILTER_PREFIX)) {
      mergedDataMask[filter?.id] = filter;
    }
  });
}

const dataMaskReducer = produce(
  (draft: DataMaskStateWithId, action: AnyDataMaskAction) => {
    const cleanState = {};
    switch (action.type) {
      case UPDATE_DATA_MASK:
        draft[action.filterId] = {
          ...getInitialDataMask(action.filterId),
          ...draft[action.filterId],
          ...action.dataMask,
        };
        return draft;
      // TODO: update hydrate to .ts
      // @ts-ignore
      case HYDRATE_DASHBOARD:
        if (isFeatureEnabled(FeatureFlag.DASHBOARD_CROSS_FILTERS)) {
          Object.keys(
            // @ts-ignore
            action.data.dashboardInfo?.metadata?.chart_configuration,
          ).forEach(id => {
            cleanState[id] = {
              ...getInitialDataMask(id), // take initial data
            };
          });
        }
        fillNativeFilters(
          // @ts-ignore
          action.data.dashboardInfo?.metadata?.native_filter_configuration ??
            [],
          cleanState,
          draft,
        );
        return cleanState;
      case SET_DATA_MASK_FOR_FILTER_CONFIG_COMPLETE:
        fillNativeFilters(
          action.filterConfig ?? [],
          cleanState,
          draft,
          action.filters,
        );
        return cleanState;

      default:
        return draft;
    }
  },
  {},
);

export default dataMaskReducer;
