// SPDX-License-Identifier: AGPL-3.0-or-later
// SPDX-FileCopyrightText: 2020-2022 grommunio GmbH

import React, { PureComponent } from 'react';
import { withStyles } from '@mui/styles';
import PropTypes from 'prop-types';
import { Dialog, DialogTitle, DialogContent, FormControl, TextField, Button, DialogActions,
  CircularProgress,
  Grid,
  Typography,
  MenuItem, 
} from '@mui/material';
import { withTranslation } from 'react-i18next';
import { connect } from 'react-redux';
import { uploadServiceFile } from '../../actions/dbconf';

const styles = theme => ({
  form: {
    width: '100%',
    marginTop: theme.spacing(4),
  },
  input: {
    marginBottom: theme.spacing(3),
  },
  select: {
    minWidth: 60,
  },
  flexTextfield: {
    flex: 1,
    margin: theme.spacing(0, 1, 0, 1),
  },
  gridTypo: {
    minWidth: 120,
    marginBottom: 2,
  },
});

class CreateDbconfFile extends PureComponent {

  constructor() {
    super();
    this.fileInputRef = React.createRef();
  }

  state = {
    data: [
      { key: 'commit_key', value: '' },
      { key: 'commit_file', value: '' },
      { key: 'commit_service', value: '' },
    ],
    service: '',
    loading: false,
  }

  commandKeys = ['key', 'file', 'service'];

  handleInput = field => event => {
    this.setState({
      [field]: event.target.value,
    });
  }

  handleDataInput = idx => e => {
    const data = [...this.state.data];
    data[idx].value = e.target.value;
    this.setState({ data });
  }

  handleUpload = () => {
    const { upload } = this.props;
    const { service, data } = this.state;
    this.setState({ loading: true });
    upload('grommunio-dbconf', service, this.formatData(data))
      .then(() => {
        this.setState({
          data: [],
          filename: '',
          service: '',
          loading: false,
        });
        this.props.onSuccess();
      })
      .catch(error => {
        this.props.onError(error);
        this.setState({ loading: false });
      });
  }

  formatData(data) {
    const obj = {};
    data.forEach(pair => obj[pair.key] = pair.value || undefined);
    return obj;
  }

  render() {
    const { classes, t, open, onClose, commands } = this.props;
    const { service, data, loading } = this.state;

    return (
      <Dialog
        onClose={onClose}
        open={open}
        maxWidth="md"
        fullWidth
      >
        <DialogTitle>Configure grommunio-dbconf</DialogTitle>
        <DialogContent style={{ minWidth: 400 }}>
          <FormControl className={classes.form}>
            <TextField 
              className={classes.input} 
              label={t("Service name")} 
              fullWidth 
              value={service || ''}
              onChange={this.handleInput('service')}
              autoFocus
              required
            />
            <Typography variant="h6">Data</Typography>
            {data.map((pair, idx) => <Grid key={idx} container alignItems="flex-end">
              <Typography className={classes.gridTypo}>
                {pair.key}
              </Typography>
              <TextField
                label="value"
                value={pair.value}
                onChange={this.handleDataInput(idx)}
                className={classes.flexTextfield}
                select
              >
                {commands[this.commandKeys[idx]].map((command, idx) =>
                  <MenuItem key={idx} value={command}>
                    {command}
                  </MenuItem>
                )}
              </TextField>
            </Grid>
            )}
          </FormControl>
        </DialogContent>
        <DialogActions>
          <Button
            onClick={onClose}
            color="secondary"
          >
            {t('Cancel')}
          </Button>
          <Button
            onClick={this.handleUpload}
            variant="contained"
            color="primary"
            disabled={loading || !service}
          >
            {loading ? <CircularProgress size={24}/> : t('Add')}
          </Button>
        </DialogActions>
      </Dialog>
    );
  }
}

CreateDbconfFile.propTypes = {
  classes: PropTypes.object.isRequired,
  t: PropTypes.func.isRequired,
  open: PropTypes.bool.isRequired,
  onSuccess: PropTypes.func.isRequired,
  onClose: PropTypes.func.isRequired,
  onError: PropTypes.func.isRequired,
  upload: PropTypes.func.isRequired,
  commands: PropTypes.object.isRequired,
};

const mapStateToProps = state => {
  return {
    commands: state.dbconf.commands,
  };
};

const mapDispatchToProps = dispatch => {
  return {
    upload: async (service, filename, file) => {
      await dispatch(uploadServiceFile(service, filename, file))
        .catch(message => Promise.reject(message));
    },
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(
  withTranslation()(withStyles(styles)(CreateDbconfFile)));