/**
 * 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 camelcase */
import { isString } from 'lodash';
import shortid from 'shortid';
import { CategoricalColorNamespace } from '@superset-ui/core';

import { initSliceEntities } from 'src/dashboard/reducers/sliceEntities';
import { getInitialState as getInitialNativeFilterState } from 'src/dashboard/reducers/nativeFilters';
import { getParam } from 'src/modules/utils';
import { applyDefaultFormData } from 'src/explore/store';
import { buildActiveFilters } from 'src/dashboard/util/activeDashboardFilters';
import {
  DASHBOARD_FILTER_SCOPE_GLOBAL,
  dashboardFilter,
} from './dashboardFilters';
import { chart } from '../../chart/chartReducer';
import {
  DASHBOARD_HEADER_ID,
  GRID_DEFAULT_CHART_WIDTH,
  GRID_COLUMN_COUNT,
} from '../util/constants';
import {
  DASHBOARD_HEADER_TYPE,
  CHART_TYPE,
  ROW_TYPE,
} from '../util/componentTypes';
import findFirstParentContainerId from '../util/findFirstParentContainer';
import getEmptyLayout from '../util/getEmptyLayout';
import getFilterConfigsFromFormdata from '../util/getFilterConfigsFromFormdata';
import getLocationHash from '../util/getLocationHash';
import newComponentFactory from '../util/newComponentFactory';
import { TIME_RANGE } from '../../visualizations/FilterBox/FilterBox';

export default function getInitialState(bootstrapData) {
  const { user_id, datasources, common, editMode, urlParams } = bootstrapData;

  const dashboard = { ...bootstrapData.dashboard_data };
  let preselectFilters = {};
  try {
    // allow request parameter overwrite dashboard metadata
    preselectFilters = JSON.parse(
      getParam('preselect_filters') || dashboard.metadata.default_filters,
    );
  } catch (e) {
    //
  }

  // Priming the color palette with user's label-color mapping provided in
  // the dashboard's JSON metadata
  if (dashboard.metadata && dashboard.metadata.label_colors) {
    const scheme = dashboard.metadata.color_scheme;
    const namespace = dashboard.metadata.color_namespace;
    const colorMap = isString(dashboard.metadata.label_colors)
      ? JSON.parse(dashboard.metadata.label_colors)
      : dashboard.metadata.label_colors;
    Object.keys(colorMap).forEach(label => {
      CategoricalColorNamespace.getScale(scheme, namespace).setColor(
        label,
        colorMap[label],
      );
    });
  }

  // dashboard layout
  const { position_json: positionJson } = dashboard;
  // new dash: positionJson could be {} or null
  const layout =
    positionJson && Object.keys(positionJson).length > 0
      ? positionJson
      : getEmptyLayout();

  // create a lookup to sync layout names with slice names
  const chartIdToLayoutId = {};
  Object.values(layout).forEach(layoutComponent => {
    if (layoutComponent.type === CHART_TYPE) {
      chartIdToLayoutId[layoutComponent.meta.chartId] = layoutComponent.id;
    }
  });

  // find root level chart container node for newly-added slices
  const parentId = findFirstParentContainerId(layout);
  const parent = layout[parentId];
  let newSlicesContainer;
  let newSlicesContainerWidth = 0;

  const filterScopes = dashboard.metadata.filter_scopes || {};

  const chartQueries = {};
  const dashboardFilters = {};
  const slices = {};
  const sliceIds = new Set();
  dashboard.slices.forEach(slice => {
    const key = slice.slice_id;
    const form_data = {
      ...slice.form_data,
      url_params: {
        ...slice.form_data.url_params,
        ...urlParams,
      },
    };
    chartQueries[key] = {
      ...chart,
      id: key,
      form_data,
      formData: applyDefaultFormData(form_data),
    };

    slices[key] = {
      slice_id: key,
      slice_url: slice.slice_url,
      slice_name: slice.slice_name,
      form_data: slice.form_data,
      viz_type: slice.form_data.viz_type,
      datasource: slice.form_data.datasource,
      description: slice.description,
      description_markeddown: slice.description_markeddown,
      owners: slice.owners,
      modified: slice.modified,
      changed_on: new Date(slice.changed_on).getTime(),
    };

    sliceIds.add(key);

    // if there are newly added slices from explore view, fill slices into 1 or more rows
    if (!chartIdToLayoutId[key] && layout[parentId]) {
      if (
        newSlicesContainerWidth === 0 ||
        newSlicesContainerWidth + GRID_DEFAULT_CHART_WIDTH > GRID_COLUMN_COUNT
      ) {
        newSlicesContainer = newComponentFactory(
          ROW_TYPE,
          (parent.parents || []).slice(),
        );
        layout[newSlicesContainer.id] = newSlicesContainer;
        parent.children.push(newSlicesContainer.id);
        newSlicesContainerWidth = 0;
      }

      const chartHolder = newComponentFactory(
        CHART_TYPE,
        {
          chartId: slice.slice_id,
        },
        (newSlicesContainer.parents || []).slice(),
      );

      layout[chartHolder.id] = chartHolder;
      newSlicesContainer.children.push(chartHolder.id);
      chartIdToLayoutId[chartHolder.meta.chartId] = chartHolder.id;
      newSlicesContainerWidth += GRID_DEFAULT_CHART_WIDTH;
    }

    // build DashboardFilters for interactive filter features
    if (
      slice.form_data.viz_type === 'filter_box' ||
      slice.form_data.viz_type === 'filter_select'
    ) {
      const configs = getFilterConfigsFromFormdata(slice.form_data);
      let { columns } = configs;
      const { labels } = configs;
      if (preselectFilters[key]) {
        Object.keys(columns).forEach(col => {
          if (preselectFilters[key][col]) {
            columns = {
              ...columns,
              [col]: preselectFilters[key][col],
            };
          }
        });
      }

      const scopesByChartId = Object.keys(columns).reduce((map, column) => {
        const scopeSettings = {
          ...filterScopes[key],
        };
        const { scope, immune } = {
          ...DASHBOARD_FILTER_SCOPE_GLOBAL,
          ...scopeSettings[column],
        };

        return {
          ...map,
          [column]: {
            scope,
            immune,
          },
        };
      }, {});

      const componentId = chartIdToLayoutId[key];
      const directPathToFilter = (layout[componentId].parents || []).slice();
      directPathToFilter.push(componentId);
      dashboardFilters[key] = {
        ...dashboardFilter,
        chartId: key,
        componentId,
        datasourceId: slice.form_data.datasource,
        filterName: slice.slice_name,
        directPathToFilter,
        columns,
        labels,
        scopes: scopesByChartId,
        isInstantFilter: !!slice.form_data.instant_filtering,
        isDateFilter: Object.keys(columns).includes(TIME_RANGE),
      };
    }

    // sync layout names with current slice names in case a slice was edited
    // in explore since the layout was updated. name updates go through layout for undo/redo
    // functionality and python updates slice names based on layout upon dashboard save
    const layoutId = chartIdToLayoutId[key];
    if (layoutId && layout[layoutId]) {
      layout[layoutId].meta.sliceName = slice.slice_name;
    }
  });
  buildActiveFilters({
    dashboardFilters,
    components: layout,
  });

  // store the header as a layout component so we can undo/redo changes
  layout[DASHBOARD_HEADER_ID] = {
    id: DASHBOARD_HEADER_ID,
    type: DASHBOARD_HEADER_TYPE,
    meta: {
      text: dashboard.dashboard_title,
    },
  };

  const dashboardLayout = {
    past: [],
    present: layout,
    future: [],
  };

  // find direct link component and path from root
  const directLinkComponentId = getLocationHash();
  let directPathToChild = [];
  if (layout[directLinkComponentId]) {
    directPathToChild = (layout[directLinkComponentId].parents || []).slice();
    directPathToChild.push(directLinkComponentId);
  }

  const nativeFilters = getInitialNativeFilterState({
    filterConfig: dashboard.metadata.native_filter_configuration || [],
    filterSetsConfig: dashboard.metadata.filter_sets_configuration || [],
  });

  return {
    datasources,
    sliceEntities: { ...initSliceEntities, slices, isLoading: false },
    charts: chartQueries,
    // read-only data
    dashboardInfo: {
      id: dashboard.id,
      slug: dashboard.slug,
      metadata: dashboard.metadata,
      userId: user_id,
      dash_edit_perm: dashboard.dash_edit_perm,
      dash_save_perm: dashboard.dash_save_perm,
      superset_can_explore: dashboard.superset_can_explore,
      superset_can_csv: dashboard.superset_can_csv,
      slice_can_edit: dashboard.slice_can_edit,
      common: {
        flash_messages: common.flash_messages,
        conf: common.conf,
      },
      lastModifiedTime: dashboard.last_modified_time,
    },
    dashboardFilters,
    nativeFilters,
    dashboardState: {
      sliceIds: Array.from(sliceIds),
      directPathToChild,
      directPathLastUpdated: Date.now(),
      focusedFilterField: null,
      expandedSlices: dashboard.metadata.expanded_slices || {},
      refreshFrequency: dashboard.metadata.refresh_frequency || 0,
      // dashboard viewers can set refresh frequency for the current visit,
      // only persistent refreshFrequency will be saved to backend
      shouldPersistRefreshFrequency: false,
      css: dashboard.css || '',
      colorNamespace: dashboard.metadata.color_namespace,
      colorScheme: dashboard.metadata.color_scheme,
      editMode: dashboard.dash_edit_perm && editMode,
      isPublished: dashboard.published,
      hasUnsavedChanges: false,
      maxUndoHistoryExceeded: false,
      lastModifiedTime: dashboard.last_modified_time,
    },
    dashboardLayout,
    messageToasts: [],
    impressionId: shortid.generate(),
  };
}
