/**
 * 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.
 */
import React, { useEffect, useRef, useState } from 'react';
import PropTypes from 'prop-types';
import { Row, Col, FormControl } from 'react-bootstrap';
import { Behavior, t, getChartMetadataRegistry } from '@superset-ui/core';
import { useDynamicPluginContext } from 'src/components/DynamicPlugins';
import { Tooltip } from 'src/common/components/Tooltip';
import Modal from 'src/common/components/Modal';
import Label from 'src/components/Label';
import ControlHeader from '../ControlHeader';
import './VizTypeControl.less';
import { FeatureFlag, isFeatureEnabled } from '../../../featureFlags';

const propTypes = {
  description: PropTypes.string,
  label: PropTypes.string,
  name: PropTypes.string.isRequired,
  onChange: PropTypes.func,
  value: PropTypes.string.isRequired,
  labelType: PropTypes.string,
};

const defaultProps = {
  onChange: () => {},
  labelType: 'default',
};

const registry = getChartMetadataRegistry();

const IMAGE_PER_ROW = 6;
const DEFAULT_ORDER = [
  'line',
  'big_number',
  'table',
  'filter_box',
  'dist_bar',
  'area',
  'bar',
  'deck_polygon',
  'pie',
  'time_table',
  'pivot_table',
  'histogram',
  'big_number_total',
  'deck_scatter',
  'deck_hex',
  'time_pivot',
  'deck_arc',
  'heatmap',
  'deck_grid',
  'dual_line',
  'deck_screengrid',
  'line_multi',
  'treemap',
  'box_plot',
  'sunburst',
  'sankey',
  'word_cloud',
  'mapbox',
  'kepler',
  'cal_heatmap',
  'rose',
  'bubble',
  'deck_geojson',
  'horizon',
  'deck_multi',
  'compare',
  'partition',
  'event_flow',
  'deck_path',
  'graph_chart',
  'world_map',
  'paired_ttest',
  'para',
  'country_map',
];

const typesWithDefaultOrder = new Set(DEFAULT_ORDER);

function VizSupportValidation({ vizType }) {
  const state = useDynamicPluginContext();
  if (state.loading || registry.has(vizType)) {
    return null;
  }
  return (
    <div className="text-danger">
      <i className="fa fa-exclamation-circle text-danger" />{' '}
      <small>{t('This visualization type is not supported.')}</small>
    </div>
  );
}

const nativeFilterGate = behaviors =>
  !behaviors.includes(Behavior.NATIVE_FILTER) ||
  (isFeatureEnabled(FeatureFlag.DASHBOARD_CROSS_FILTERS) &&
    behaviors.includes(Behavior.CROSS_FILTER));

const VizTypeControl = props => {
  const [showModal, setShowModal] = useState(false);
  const [filter, setFilter] = useState('');
  const searchRef = useRef(null);

  useEffect(() => {
    if (showModal) {
      searchRef?.current?.focus();
    }
  }, [showModal]);

  const onChange = vizType => {
    props.onChange(vizType);
    setShowModal(false);
  };

  const toggleModal = () => {
    setShowModal(prevState => !prevState);
  };

  const changeSearch = event => {
    setFilter(event.target.value);
  };

  const focusSearch = () => {
    if (searchRef) {
      searchRef.focus();
    }
  };

  const renderItem = entry => {
    const { value } = props;
    const { key, value: type } = entry;
    const isSelected = key === value;

    return (
      <div
        role="button"
        tabIndex={0}
        className={`viztype-selector-container ${isSelected ? 'selected' : ''}`}
        onClick={() => onChange(key)}
      >
        <img
          alt={type.name}
          width="100%"
          className={`viztype-selector ${isSelected ? 'selected' : ''}`}
          src={type.thumbnail}
        />
        <div className="viztype-label" data-test="viztype-label">
          {type.name}
        </div>
      </div>
    );
  };

  const { value, labelType } = props;
  const filterString = filter.toLowerCase();

  const filteredTypes = DEFAULT_ORDER.filter(type => registry.has(type))
    .filter(type => {
      const behaviors = registry.get(type)?.behaviors || [];
      return nativeFilterGate(behaviors);
    })
    .map(type => ({
      key: type,
      value: registry.get(type),
    }))
    .concat(
      registry
        .entries()
        .filter(entry => {
          const behaviors = entry.value?.behaviors || [];
          return nativeFilterGate(behaviors);
        })
        .filter(({ key }) => !typesWithDefaultOrder.has(key)),
    )
    .filter(entry => entry.value.name.toLowerCase().includes(filterString));

  const rows = [];
  for (let i = 0; i <= filteredTypes.length; i += IMAGE_PER_ROW) {
    rows.push(
      <Row data-test="viz-row" key={`row-${i}`}>
        {filteredTypes.slice(i, i + IMAGE_PER_ROW).map(entry => (
          <Col md={12 / IMAGE_PER_ROW} key={`grid-col-${entry.key}`}>
            {renderItem(entry)}
          </Col>
        ))}
      </Row>,
    );
  }

  return (
    <div>
      <ControlHeader {...props} />
      <Tooltip
        id="error-tooltip"
        placement="right"
        title={t('Click to change visualization type')}
      >
        <>
          <Label
            onClick={toggleModal}
            type={labelType}
            data-test="visualization-type"
          >
            {registry.has(value) ? registry.get(value).name : `${value}`}
          </Label>
          <VizSupportValidation vizType={value} />
        </>
      </Tooltip>
      <Modal
        show={showModal}
        onHide={toggleModal}
        onEnter={focusSearch}
        title={t('Select a visualization type')}
        responsive
        hideFooter
        forceRender
      >
        <div className="viztype-control-search-box">
          <FormControl
            inputRef={ref => {
              searchRef.current = ref;
            }}
            type="text"
            value={filter}
            placeholder={t('Search')}
            onChange={changeSearch}
          />
        </div>
        {rows}
      </Modal>
    </div>
  );
};

VizTypeControl.propTypes = propTypes;
VizTypeControl.defaultProps = defaultProps;

export default VizTypeControl;
