/**
 * 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 { Component } from 'react';
import PropTypes from 'prop-types';
import { debounce } from 'lodash';
import {
  Input,
  Tooltip,
  Button,
  TextAreaEditor,
  ModalTrigger,
} from '@superset-ui/core/components';
import { t, withTheme } from '@superset-ui/core';

import 'ace-builds/src-min-noconflict/mode-handlebars';

import ControlHeader from 'src/explore/components/ControlHeader';

const propTypes = {
  name: PropTypes.string,
  onChange: PropTypes.func,
  initialValue: PropTypes.string,
  height: PropTypes.number,
  minLines: PropTypes.number,
  maxLines: PropTypes.number,
  offerEditInModal: PropTypes.bool,
  language: PropTypes.oneOf([
    null,
    'json',
    'html',
    'sql',
    'markdown',
    'javascript',
    'handlebars',
  ]),
  aboveEditorSection: PropTypes.node,
  readOnly: PropTypes.bool,
  resize: PropTypes.oneOf([
    null,
    'block',
    'both',
    'horizontal',
    'inline',
    'none',
    'vertical',
  ]),
  textAreaStyles: PropTypes.object,
  tooltipOptions: PropTypes.object,
  hotkeys: PropTypes.array,
  debounceDelay: PropTypes.number,
};

const defaultProps = {
  onChange: () => {},
  initialValue: '',
  height: 250,
  minLines: 3,
  maxLines: 10,
  offerEditInModal: true,
  readOnly: false,
  resize: null,
  textAreaStyles: {},
  tooltipOptions: {},
  hotkeys: [],
  debounceDelay: null,
};

class TextAreaControl extends Component {
  constructor(props) {
    super(props);
    if (props.debounceDelay) {
      this.debouncedOnChange = debounce(props.onChange, props.debounceDelay);
    }
  }

  componentDidUpdate(prevProps) {
    if (
      this.props.onChange !== prevProps.onChange &&
      this.props.debounceDelay
    ) {
      if (this.debouncedOnChange) {
        this.debouncedOnChange.cancel();
      }
      this.debouncedOnChange = debounce(
        this.props.onChange,
        this.props.debounceDelay,
      );
    }
  }

  handleChange(value) {
    const finalValue = typeof value === 'object' ? value.target.value : value;
    if (this.debouncedOnChange) {
      this.debouncedOnChange(finalValue);
    } else {
      this.props.onChange(finalValue);
    }
  }

  componentWillUnmount() {
    if (this.debouncedOnChange) {
      this.debouncedOnChange.cancel();
    }
  }

  renderEditor(inModal = false) {
    const minLines = inModal ? 40 : this.props.minLines || 12;
    if (this.props.language) {
      const style = {
        border: `1px solid ${this.props.theme.colorBorder}`,
        minHeight: `${minLines}em`,
        width: 'auto',
        ...this.props.textAreaStyles,
      };
      if (this.props.resize) {
        style.resize = this.props.resize;
      }
      if (this.props.readOnly) {
        style.backgroundColor = '#f2f2f2';
      }
      const onEditorLoad = editor => {
        this.props.hotkeys.forEach(keyConfig => {
          editor.commands.addCommand({
            name: keyConfig.name,
            bindKey: { win: keyConfig.key, mac: keyConfig.key },
            exec: keyConfig.func,
          });
        });
      };
      const codeEditor = (
        <div>
          <TextAreaEditor
            mode={this.props.language}
            style={style}
            minLines={minLines}
            maxLines={inModal ? 1000 : this.props.maxLines}
            editorProps={{ $blockScrolling: true }}
            onLoad={onEditorLoad}
            defaultValue={this.props.initialValue}
            readOnly={this.props.readOnly}
            key={this.props.name}
            {...this.props}
            onChange={this.handleChange.bind(this)}
          />
        </div>
      );

      if (this.props.tooltipOptions) {
        return <Tooltip {...this.props.tooltipOptions}>{codeEditor}</Tooltip>;
      }
      return codeEditor;
    }

    const textArea = (
      <div>
        <Input.TextArea
          placeholder={t('textarea')}
          onChange={this.handleChange.bind(this)}
          defaultValue={this.props.initialValue}
          disabled={this.props.readOnly}
          style={{ height: this.props.height }}
          aria-required={this.props['aria-required']}
        />
      </div>
    );
    if (this.props.tooltipOptions) {
      return <Tooltip {...this.props.tooltipOptions}>{textArea}</Tooltip>;
    }
    return textArea;
  }

  renderModalBody() {
    return (
      <>
        <div>{this.props.aboveEditorSection}</div>
        {this.renderEditor(true)}
      </>
    );
  }

  render() {
    const controlHeader = <ControlHeader {...this.props} />;
    return (
      <div>
        {controlHeader}
        {this.renderEditor()}
        {this.props.offerEditInModal && (
          <ModalTrigger
            modalTitle={controlHeader}
            triggerNode={
              <Button
                buttonSize="small"
                style={{ marginTop: this.props.theme.sizeUnit }}
              >
                {t('Edit')} <strong>{this.props.language}</strong>{' '}
                {t('in modal')}
              </Button>
            }
            modalBody={this.renderModalBody(true)}
            responsive
          />
        )}
      </div>
    );
  }
}

TextAreaControl.propTypes = propTypes;
TextAreaControl.defaultProps = defaultProps;

export default withTheme(TextAreaControl);
