/**
 * 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-env browser */
import moment from 'moment';
import React from 'react';
import PropTypes from 'prop-types';
import { styled, CategoricalColorNamespace, t } from '@superset-ui/core';
import ButtonGroup from 'src/components/ButtonGroup';

import {
  LOG_ACTIONS_PERIODIC_RENDER_DASHBOARD,
  LOG_ACTIONS_FORCE_REFRESH_DASHBOARD,
  LOG_ACTIONS_TOGGLE_EDIT_DASHBOARD,
} from 'src/logger/LogUtils';

import Icons from 'src/components/Icons';
import Button from 'src/components/Button';
import EditableTitle from 'src/components/EditableTitle';
import FaveStar from 'src/components/FaveStar';
import { safeStringify } from 'src/utils/safeStringify';
import HeaderActionsDropdown from 'src/dashboard/components/Header/HeaderActionsDropdown';
import PublishedStatus from 'src/dashboard/components/PublishedStatus';
import UndoRedoKeyListeners from 'src/dashboard/components/UndoRedoKeyListeners';
import PropertiesModal from 'src/dashboard/components/PropertiesModal';
import { chartPropShape } from 'src/dashboard/util/propShapes';
import {
  UNDO_LIMIT,
  SAVE_TYPE_OVERWRITE,
  DASHBOARD_POSITION_DATA_LIMIT,
} from 'src/dashboard/util/constants';
import setPeriodicRunner from 'src/dashboard/util/setPeriodicRunner';
import { options as PeriodicRefreshOptions } from 'src/dashboard/components/RefreshIntervalModal';

const propTypes = {
  addSuccessToast: PropTypes.func.isRequired,
  addDangerToast: PropTypes.func.isRequired,
  addWarningToast: PropTypes.func.isRequired,
  userId: PropTypes.number,
  dashboardInfo: PropTypes.object.isRequired,
  dashboardTitle: PropTypes.string.isRequired,
  dataMask: PropTypes.object.isRequired,
  charts: PropTypes.objectOf(chartPropShape).isRequired,
  layout: PropTypes.object.isRequired,
  expandedSlices: PropTypes.object.isRequired,
  customCss: PropTypes.string.isRequired,
  colorNamespace: PropTypes.string,
  colorScheme: PropTypes.string,
  setColorSchemeAndUnsavedChanges: PropTypes.func.isRequired,
  isStarred: PropTypes.bool.isRequired,
  isPublished: PropTypes.bool.isRequired,
  isLoading: PropTypes.bool.isRequired,
  onSave: PropTypes.func.isRequired,
  onChange: PropTypes.func.isRequired,
  fetchFaveStar: PropTypes.func.isRequired,
  fetchCharts: PropTypes.func.isRequired,
  saveFaveStar: PropTypes.func.isRequired,
  savePublished: PropTypes.func.isRequired,
  updateDashboardTitle: PropTypes.func.isRequired,
  editMode: PropTypes.bool.isRequired,
  setEditMode: PropTypes.func.isRequired,
  showBuilderPane: PropTypes.func.isRequired,
  updateCss: PropTypes.func.isRequired,
  logEvent: PropTypes.func.isRequired,
  hasUnsavedChanges: PropTypes.bool.isRequired,
  maxUndoHistoryExceeded: PropTypes.bool.isRequired,
  lastModifiedTime: PropTypes.number.isRequired,

  // redux
  onRefresh: PropTypes.func.isRequired,
  onUndo: PropTypes.func.isRequired,
  onRedo: PropTypes.func.isRequired,
  undoLength: PropTypes.number.isRequired,
  redoLength: PropTypes.number.isRequired,
  setMaxUndoHistoryExceeded: PropTypes.func.isRequired,
  maxUndoHistoryToast: PropTypes.func.isRequired,
  refreshFrequency: PropTypes.number.isRequired,
  shouldPersistRefreshFrequency: PropTypes.bool.isRequired,
  setRefreshFrequency: PropTypes.func.isRequired,
  dashboardInfoChanged: PropTypes.func.isRequired,
  dashboardTitleChanged: PropTypes.func.isRequired,
};

const defaultProps = {
  colorNamespace: undefined,
  colorScheme: undefined,
};

// Styled Components
const StyledDashboardHeader = styled.div`
  background: ${({ theme }) => theme.colors.grayscale.light5};
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  padding: 0 ${({ theme }) => theme.gridUnit * 6}px;
  border-bottom: 1px solid ${({ theme }) => theme.colors.grayscale.light2};

  .action-button > span {
    color: ${({ theme }) => theme.colors.grayscale.base};
  }
  button,
  .fave-unfave-icon {
    margin-left: ${({ theme }) => theme.gridUnit * 2}px;
  }
  .button-container {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    .action-button {
      font-size: ${({ theme }) => theme.typography.sizes.xl}px;
    }
  }
`;

class Header extends React.PureComponent {
  static discardChanges() {
    const url = new URL(window.location.href);

    url.searchParams.delete('edit');
    window.location.assign(url);
  }

  constructor(props) {
    super(props);
    this.state = {
      didNotifyMaxUndoHistoryToast: false,
      emphasizeUndo: false,
      showingPropertiesModal: false,
    };

    this.handleChangeText = this.handleChangeText.bind(this);
    this.handleCtrlZ = this.handleCtrlZ.bind(this);
    this.handleCtrlY = this.handleCtrlY.bind(this);
    this.toggleEditMode = this.toggleEditMode.bind(this);
    this.forceRefresh = this.forceRefresh.bind(this);
    this.startPeriodicRender = this.startPeriodicRender.bind(this);
    this.overwriteDashboard = this.overwriteDashboard.bind(this);
    this.showPropertiesModal = this.showPropertiesModal.bind(this);
    this.hidePropertiesModal = this.hidePropertiesModal.bind(this);
  }

  componentDidMount() {
    const { refreshFrequency } = this.props;
    this.startPeriodicRender(refreshFrequency * 1000);
  }

  UNSAFE_componentWillReceiveProps(nextProps) {
    if (
      UNDO_LIMIT - nextProps.undoLength <= 0 &&
      !this.state.didNotifyMaxUndoHistoryToast
    ) {
      this.setState(() => ({ didNotifyMaxUndoHistoryToast: true }));
      this.props.maxUndoHistoryToast();
    }
    if (
      nextProps.undoLength > UNDO_LIMIT &&
      !this.props.maxUndoHistoryExceeded
    ) {
      this.props.setMaxUndoHistoryExceeded();
    }
  }

  componentWillUnmount() {
    clearTimeout(this.ctrlYTimeout);
    clearTimeout(this.ctrlZTimeout);
  }

  handleChangeText(nextText) {
    const { updateDashboardTitle, onChange } = this.props;
    if (nextText && this.props.dashboardTitle !== nextText) {
      updateDashboardTitle(nextText);
      onChange();
    }
  }

  handleCtrlY() {
    this.props.onRedo();
    this.setState({ emphasizeRedo: true }, () => {
      if (this.ctrlYTimeout) clearTimeout(this.ctrlYTimeout);
      this.ctrlYTimeout = setTimeout(() => {
        this.setState({ emphasizeRedo: false });
      }, 100);
    });
  }

  handleCtrlZ() {
    this.props.onUndo();
    this.setState({ emphasizeUndo: true }, () => {
      if (this.ctrlZTimeout) clearTimeout(this.ctrlZTimeout);
      this.ctrlZTimeout = setTimeout(() => {
        this.setState({ emphasizeUndo: false });
      }, 100);
    });
  }

  forceRefresh() {
    if (!this.props.isLoading) {
      const chartList = Object.keys(this.props.charts);
      this.props.logEvent(LOG_ACTIONS_FORCE_REFRESH_DASHBOARD, {
        force: true,
        interval: 0,
        chartCount: chartList.length,
      });
      return this.props.onRefresh(
        chartList,
        true,
        0,
        this.props.dashboardInfo.id,
      );
    }
    return false;
  }

  startPeriodicRender(interval) {
    let intervalMessage;
    if (interval) {
      const predefinedValue = PeriodicRefreshOptions.find(
        option => option.value === interval / 1000,
      );
      if (predefinedValue) {
        intervalMessage = predefinedValue.label;
      } else {
        intervalMessage = moment.duration(interval, 'millisecond').humanize();
      }
    }

    const periodicRender = () => {
      const { fetchCharts, logEvent, charts, dashboardInfo } = this.props;
      const { metadata } = dashboardInfo;
      const immune = metadata.timed_refresh_immune_slices || [];
      const affectedCharts = Object.values(charts)
        .filter(chart => immune.indexOf(chart.id) === -1)
        .map(chart => chart.id);

      logEvent(LOG_ACTIONS_PERIODIC_RENDER_DASHBOARD, {
        interval,
        chartCount: affectedCharts.length,
      });
      this.props.addWarningToast(
        t(
          `This dashboard is currently force refreshing; the next force refresh will be in %s.`,
          intervalMessage,
        ),
      );

      return fetchCharts(
        affectedCharts,
        true,
        interval * 0.2,
        dashboardInfo.id,
      );
    };

    this.refreshTimer = setPeriodicRunner({
      interval,
      periodicRender,
      refreshTimer: this.refreshTimer,
    });
  }

  toggleEditMode() {
    this.props.logEvent(LOG_ACTIONS_TOGGLE_EDIT_DASHBOARD, {
      edit_mode: !this.props.editMode,
    });
    this.props.setEditMode(!this.props.editMode);
  }

  overwriteDashboard() {
    const {
      dashboardTitle,
      layout: positions,
      expandedSlices,
      customCss,
      colorNamespace,
      colorScheme,
      dashboardInfo,
      refreshFrequency: currentRefreshFrequency,
      shouldPersistRefreshFrequency,
      lastModifiedTime,
    } = this.props;

    const scale = CategoricalColorNamespace.getScale(
      colorScheme,
      colorNamespace,
    );

    // use the colorScheme for default labels
    let labelColors = colorScheme ? scale.getColorMap() : {};
    // but allow metadata to overwrite if it exists
    // eslint-disable-next-line camelcase
    const metadataLabelColors = dashboardInfo.metadata?.label_colors;
    if (metadataLabelColors) {
      labelColors = { ...labelColors, ...metadataLabelColors };
    }

    // check refresh frequency is for current session or persist
    const refreshFrequency = shouldPersistRefreshFrequency
      ? currentRefreshFrequency
      : dashboardInfo.metadata?.refresh_frequency; // eslint-disable-line camelcase

    const data = {
      positions,
      expanded_slices: expandedSlices,
      css: customCss,
      color_namespace: colorNamespace,
      color_scheme: colorScheme,
      label_colors: labelColors,
      dashboard_title: dashboardTitle,
      refresh_frequency: refreshFrequency,
      last_modified_time: lastModifiedTime,
    };

    // make sure positions data less than DB storage limitation:
    const positionJSONLength = safeStringify(positions).length;
    const limit =
      dashboardInfo.common.conf.SUPERSET_DASHBOARD_POSITION_DATA_LIMIT ||
      DASHBOARD_POSITION_DATA_LIMIT;
    if (positionJSONLength >= limit) {
      this.props.addDangerToast(
        t(
          'Your dashboard is too large. Please reduce its size before saving it.',
        ),
      );
    } else {
      if (positionJSONLength >= limit * 0.9) {
        this.props.addWarningToast('Your dashboard is near the size limit.');
      }

      this.props.onSave(data, dashboardInfo.id, SAVE_TYPE_OVERWRITE);
    }
  }

  showPropertiesModal() {
    this.setState({ showingPropertiesModal: true });
  }

  hidePropertiesModal() {
    this.setState({ showingPropertiesModal: false });
  }

  render() {
    const {
      dashboardTitle,
      layout,
      expandedSlices,
      customCss,
      colorNamespace,
      dataMask,
      setColorSchemeAndUnsavedChanges,
      colorScheme,
      onUndo,
      onRedo,
      undoLength,
      redoLength,
      onChange,
      onSave,
      updateCss,
      editMode,
      isPublished,
      userId,
      dashboardInfo,
      hasUnsavedChanges,
      isLoading,
      refreshFrequency,
      shouldPersistRefreshFrequency,
      setRefreshFrequency,
      lastModifiedTime,
    } = this.props;

    const userCanEdit = dashboardInfo.dash_edit_perm;
    const userCanShare = dashboardInfo.dash_share_perm;
    const userCanSaveAs = dashboardInfo.dash_save_perm;
    const refreshLimit =
      dashboardInfo.common.conf.SUPERSET_DASHBOARD_PERIODICAL_REFRESH_LIMIT;
    const refreshWarning =
      dashboardInfo.common.conf
        .SUPERSET_DASHBOARD_PERIODICAL_REFRESH_WARNING_MESSAGE;

    return (
      <StyledDashboardHeader
        className="dashboard-header"
        data-test="dashboard-header"
        data-test-id={`${dashboardInfo.id}`}
      >
        <div className="dashboard-component-header header-large">
          <EditableTitle
            title={dashboardTitle}
            canEdit={userCanEdit && editMode}
            onSaveTitle={this.handleChangeText}
            showTooltip={false}
          />
          <PublishedStatus
            dashboardId={dashboardInfo.id}
            isPublished={isPublished}
            savePublished={this.props.savePublished}
            canEdit={userCanEdit}
            canSave={userCanSaveAs}
          />
          {userId && (
            <FaveStar
              itemId={dashboardInfo.id}
              fetchFaveStar={this.props.fetchFaveStar}
              saveFaveStar={this.props.saveFaveStar}
              isStarred={this.props.isStarred}
              showTooltip
            />
          )}
        </div>

        <div className="button-container">
          {userCanSaveAs && (
            <div
              className="button-container"
              data-test="dashboard-edit-actions"
            >
              {editMode && (
                <>
                  <ButtonGroup className="m-r-5">
                    <Button
                      buttonSize="small"
                      onClick={onUndo}
                      disabled={undoLength < 1}
                      buttonStyle={
                        this.state.emphasizeUndo ? 'primary' : undefined
                      }
                    >
                      <i
                        title="Undo"
                        className="undo-action fa fa-reply"
                        data-test="undo-action"
                      />
                      &nbsp;
                    </Button>
                    <Button
                      buttonSize="small"
                      onClick={onRedo}
                      disabled={redoLength < 1}
                      buttonStyle={
                        this.state.emphasizeRedo ? 'primary' : undefined
                      }
                    >
                      &nbsp;
                      <i title="Redo" className="redo-action fa fa-share" />
                    </Button>
                  </ButtonGroup>
                  <Button
                    buttonSize="small"
                    className="m-r-5"
                    onClick={this.constructor.discardChanges}
                    buttonStyle="default"
                    data-test="discard-changes-button"
                  >
                    {t('Discard changes')}
                  </Button>
                  <Button
                    buttonSize="small"
                    disabled={!hasUnsavedChanges}
                    buttonStyle="primary"
                    onClick={this.overwriteDashboard}
                    data-test="header-save-button"
                  >
                    {t('Save')}
                  </Button>
                </>
              )}
            </div>
          )}
          {editMode && (
            <UndoRedoKeyListeners
              onUndo={this.handleCtrlZ}
              onRedo={this.handleCtrlY}
            />
          )}

          {!editMode && userCanEdit && (
            <>
              <span
                role="button"
                title={t('Edit dashboard')}
                tabIndex={0}
                className="action-button"
                onClick={this.toggleEditMode}
              >
                <Icons.EditAlt />
              </span>
            </>
          )}

          {this.state.showingPropertiesModal && (
            <PropertiesModal
              dashboardId={dashboardInfo.id}
              show={this.state.showingPropertiesModal}
              onHide={this.hidePropertiesModal}
              colorScheme={this.props.colorScheme}
              onSubmit={updates => {
                const {
                  dashboardInfoChanged,
                  dashboardTitleChanged,
                } = this.props;
                dashboardInfoChanged({
                  slug: updates.slug,
                  metadata: JSON.parse(updates.jsonMetadata),
                });
                setColorSchemeAndUnsavedChanges(updates.colorScheme);
                dashboardTitleChanged(updates.title);
                if (updates.slug) {
                  window.history.pushState(
                    { event: 'dashboard_properties_changed' },
                    '',
                    `/superset/dashboard/${updates.slug}/`,
                  );
                }
              }}
            />
          )}

          <HeaderActionsDropdown
            addSuccessToast={this.props.addSuccessToast}
            addDangerToast={this.props.addDangerToast}
            dashboardId={dashboardInfo.id}
            dashboardTitle={dashboardTitle}
            dashboardInfo={dashboardInfo}
            dataMask={dataMask}
            layout={layout}
            expandedSlices={expandedSlices}
            customCss={customCss}
            colorNamespace={colorNamespace}
            colorScheme={colorScheme}
            onSave={onSave}
            onChange={onChange}
            forceRefreshAllCharts={this.forceRefresh}
            startPeriodicRender={this.startPeriodicRender}
            refreshFrequency={refreshFrequency}
            shouldPersistRefreshFrequency={shouldPersistRefreshFrequency}
            setRefreshFrequency={setRefreshFrequency}
            updateCss={updateCss}
            editMode={editMode}
            hasUnsavedChanges={hasUnsavedChanges}
            userCanEdit={userCanEdit}
            userCanShare={userCanShare}
            userCanSave={userCanSaveAs}
            isLoading={isLoading}
            showPropertiesModal={this.showPropertiesModal}
            refreshLimit={refreshLimit}
            refreshWarning={refreshWarning}
            lastModifiedTime={lastModifiedTime}
          />
        </div>
      </StyledDashboardHeader>
    );
  }
}

Header.propTypes = propTypes;
Header.defaultProps = defaultProps;

export default Header;
