/* eslint-disable react/jsx-key */
/* eslint-disable radix */
/* eslint-disable no-nested-ternary */
/* eslint-disable react/jsx-props-no-spreading */
import { useEffect, useState } from 'react';
import { Grid, Paper, Button, TextField } from '@mui/material';
import { makeStyles } from '@mui/styles';
import {
  DataGrid,
  GridEventListener,
  GridColDef,
  GridToolbar,
} from '@mui/x-data-grid';
import Typography from '@mui/material/Typography';
import NumberFormat from 'react-number-format';
import { observer } from 'mobx-react';
import { customAlphabet } from 'nanoid';
import { draft } from 'mobx-keystone';
import { useTranslation } from 'react-i18next';
import User from '../../models/Application/User';
import { getRootStore } from '../../models/root-store';

const nanoid = customAlphabet('12346789', 4);

function NumberFormatPincode(props: any) {
  const { inputRef, onChange, ...other } = props;

  return (
    <NumberFormat
      {...other}
      getInputRef={inputRef}
      defaultValue="0000"
      type="text"
      onValueChange={(values) => {
        onChange({
          target: {
            name: props.name,
            value: values.value,
          },
        });
      }}
    />
  );
}

const useStyles = makeStyles({
  dataGrid: {
    border: 0,
    color: 'white',
  },
  content: {
    alignItems: 'center',
  },
  root: {
    flexGrow: 1,
  },
  paper: {
    backgroundColor: '#95A5A6',
    textAlign: 'center',
  },
  paperInput: {
    alignItems: 'center',
    justifyContentContentContentContentItems: 'baseline',
    padding: 10,
    margin: 10,
    minHeight: 70,
  },
  buttons: {
    alignItems: 'center',
    alignSelf: 'center',
    marginRight: 35,
    minHeight: 70,
    padding: 0,
    margin: 0,
  },
  button: {
    backgroundColor: '#3E3E3E',
    height: '90%',
    width: '90%',
    margin: 25,
    padding: 25,
    textAlign: 'center',
  },
  typo: {
    fontSize: 'auto',
  },
  paperTop: {
    alignItems: 'center',
    padding: 10,
    marginTop: 15,
    margin: 15,
  },
  typoAddTicket: {
    marginLeft: 25,
    marginTop: 10,
    marginBottom: 10,
  },
  input: {
    color: 'white',
    fontSize: '1.1em',
    padding: '5px',
    width: 'auto',
  },
  inputLabel: {
    color: 'lightgrey',
    fontSize: '20px',
  },
  inputNumbers: {
    color: 'white',
    fontSize: '1.2em',
    padding: '5px',
    width: 'auto',
  },
});

function Configuration() {
  const classes = useStyles();
  const [rootStore] = useState(() => getRootStore());
  const [rows, setRows] = useState<User[]>(rootStore.userList.all);
  const [selectedRows, setSelectedRows] = useState<any>([]);
  const [newName, setNewName] = useState('User');
  const startPincode = () => {
    let codeAttempt = nanoid();
    while (rootStore.userList.checkCode(codeAttempt)) {
      codeAttempt = nanoid();
    }
    return codeAttempt;
  };
  const [newPincode, setNewPincode] = useState(startPincode);
  const [newLevel, setNewLevel] = useState(1);
  const [userListDraft, setUserListDraft] = useState<any>();
  const [editName, setEditName] = useState('');
  const [editPincode, setEditPincode] = useState('');
  const [editLevel, setEditLevel] = useState(1);
  const [editId, setEditId] = useState('');
  const [editMode, setEditMode] = useState(false);
  const [userListDraftRowIndex, setUserListDraftRowIndex] = useState(0);

  useEffect(() => {
    if (rows !== rootStore.userList.all) {
      setRows(rootStore.userList.all);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [rootStore.userList]);

  const submit = (e: any) => {
    e.preventDefault();
    if (newPincode.length !== 4 || rootStore.userList.checkCode(newPincode)) {
      return;
    }
    rootStore.userList.add(
      new User({
        name: newName,
        pincode: newPincode,
        userlevel: newLevel,
      })
    );
    setRows(rootStore.userList.all);
    setNewName('User');
    setNewPincode(startPincode);
    setNewLevel(1);
  };

  const submitChange = (e: any) => {
    e.preventDefault();
    userListDraft.data.all[userListDraftRowIndex].change(
      editName,
      editPincode,
      editLevel
    );
    if (editPincode.length === 4) {
      if (!userListDraft.data.checkCodeWithoutElement(editId, editPincode)) {
        userListDraft.commit();
        setRows(rootStore.userList.all);
        setEditName('');
        setEditPincode('');
        setEditLevel(1);
        setEditId('');
        setEditMode(false);
        setSelectedRows([]);
      }
    }
  };

  const cancelChange = () => {
    userListDraft.commit();
    setRows(rootStore.userList.all);
    setEditName('');
    setEditPincode('');
    setEditLevel(1);
    setEditId('');
    setEditMode(false);
  };

  const resetChange = () => {
    userListDraft.reset();
    const elementPos = userListDraft.data.all
      .map(function (u: User) {
        return u.id;
      })
      .indexOf(editId);
    setEditMode(true);
    setUserListDraftRowIndex(elementPos);
    setEditName(userListDraft.data.all[elementPos].name);
    setEditPincode(userListDraft.data.all[elementPos].pincode);
    setEditLevel(userListDraft.data.all[elementPos].userlevel);
  };

  const handlePurge = () => {
    rootStore.userList.removeByIds(selectedRows);
    setRows(rootStore.userList.all);
    setSelectedRows([]);
  };

  const handleEdit = () => {
    const valuesSelection = selectedRows[0];
    const userDraft = draft(rootStore.userList);

    setUserListDraft(userDraft);

    const elementPos = userDraft.data.all
      .map(function (u: User) {
        return u.id;
      })
      .indexOf(valuesSelection);
    setEditMode(true);
    setUserListDraftRowIndex(elementPos);
    setEditId(userDraft.data.all[elementPos].id);
    setEditName(userDraft.data.all[elementPos].name);
    setEditPincode(userDraft.data.all[elementPos].pincode);
    setEditLevel(userDraft.data.all[elementPos].userlevel);
  };

  const handleSelectionChange: GridEventListener<'rowClick'> = (params) => {
    setSelectedRows([params.row.id]);
    if (params.row.length === 0) {
      setEditMode(false);
    }
  };

  const { t } = useTranslation();
  const columns: GridColDef[] = [
    { field: 'name', headerName: t('common.Name'), flex: 1 },
    { field: 'pincode', headerName: t('userGrid.Pincode'), width: 130 },
    { field: 'userlevel', headerName: t('userGrid.User level'), width: 250 },
  ];
  return (
    <Paper
      elevation={3}
      className={classes.paperTop}
      style={{
        background: `${rootStore.settings.backgroundColor}`,
        marginBottom: 60,
      }}
    >
      <Typography
        className={classes.content}
        style={{ color: rootStore.settings.darkMode ? 'white' : 'black' }}
        variant="h4"
      >
        {t('userGrid.Title')}
      </Typography>
      <Paper className={classes.paperInput}>
        <Grid container spacing={0}>
          <Grid
            item
            xs={12}
            style={{ height: rootStore.settings.gridHeight, width: '100%' }}
          >
            <DataGrid
              className={classes.dataGrid}
              rows={rows}
              components={{
                Toolbar: GridToolbar,
              }}
              columns={columns}
              onRowClick={handleSelectionChange}
              localeText={{
                columnMenuSortAsc: t('grid.columnMenuSortAsc'),
                columnMenuSortDesc: t('grid.columnMenuSortDesc'),
                columnMenuFilter: t('grid.columnMenuFilter'),
                columnMenuHideColumn: t('grid.columnMenuHideColumn'),
                columnMenuShowColumns: t('grid.columnMenuShowColumns'),
                columnMenuUnsort: t('grid.columnMenuUnsort'),
                noRowsLabel: t('grid.noRowsLabel'),
                footerRowSelected: (count) =>
                  count !== 1
                    ? `${count.toLocaleString()} ${t('grid.rowsSelected')}`
                    : `${count.toLocaleString()} ${t('grid.rowSelected')}`,
              }}
            />
          </Grid>
        </Grid>
        {selectedRows.length > 0 ? (
          <Button
            sx={{ margin: 3, marginLeft: 0 }}
            variant="contained"
            color="primary"
            style={{ backgroundColor: '#f44336' }}
            onClick={handlePurge}
          >
            {t('common.Delete-button')}
          </Button>
        ) : null}
        {selectedRows.length === 1 ? (
          <Button
            sx={{ margin: 3 }}
            style={{ marginLeft: 20 }}
            variant="contained"
            color="primary"
            onClick={handleEdit}
          >
            {t('common.Edit-button')}
          </Button>
        ) : null}
      </Paper>

      <Paper className={classes.paperInput}>
        {editMode ? (
          <Grid container spacing={0}>
            <Grid
              item
              xs={11}
              sm={11}
              md={11}
              lg={11}
              className={classes.content}
            >
              <Typography className={classes.typoAddTicket} variant="h6">
                {t('userGrid.Modify User')}:
              </Typography>
            </Grid>
            <Grid
              item
              xs={12}
              sm={12}
              md={12}
              lg={12}
              className={classes.content}
            >
              <Grid container spacing={0}>
                <Grid
                  item
                  xs={12}
                  sm={5}
                  md={4}
                  lg={2}
                  className={classes.paperInput}
                >
                  <form
                    onSubmit={(e) => {
                      submit(e);
                    }}
                  >
                    <TextField
                      label={t('common.Name')}
                      value={editName}
                      placeholder={t('common.Name')}
                      variant="outlined"
                      fullWidth
                      onChange={(ev) => {
                        setEditName(ev.target.value || '');
                      }}
                      InputProps={{
                        className: classes.input,
                      }}
                      InputLabelProps={{
                        className: classes.inputLabel,
                      }}
                    />
                  </form>
                </Grid>
                <Grid
                  item
                  xs={12}
                  sm={6}
                  md={4}
                  lg={5}
                  className={classes.paperInput}
                >
                  <form
                    onSubmit={(e) => {
                      submit(e);
                    }}
                  >
                    <TextField
                      label={t('userGrid.EditPincode')}
                      value={editPincode}
                      variant="outlined"
                      autoComplete="false"
                      autoCorrect="false"
                      type="string"
                      required
                      error={
                        editPincode.length !== 4 ||
                        userListDraft.data.checkCodeWithoutElement(
                          editId,
                          editPincode
                        )
                      }
                      helperText={
                        editPincode.length !== 4
                          ? t('userGrid.Code to short')
                          : userListDraft.data.checkCodeWithoutElement(
                              editId,
                              editPincode
                            )
                          ? t('userGrid.Code already used')
                          : 'Code OK'
                      }
                      fullWidth
                      onChange={(ev) => {
                        setEditPincode(ev.target.value);
                      }}
                      InputProps={{
                        className: classes.input,
                      }}
                      InputLabelProps={{
                        className: classes.inputLabel,
                      }}
                    />
                  </form>
                </Grid>
                <Grid item xs={12} sm={4} lg={3} className={classes.paperInput}>
                  <TextField
                    variant="outlined"
                    label={t('common.level')}
                    value={editLevel}
                    placeholder={t('common.level')}
                    onChange={(ev) => {
                      setEditLevel(parseInt(ev.target.value) || 1);
                    }}
                    InputProps={{
                      className: classes.inputNumbers,
                    }}
                    InputLabelProps={{
                      className: classes.inputLabel,
                    }}
                  />
                </Grid>
                <Grid item xs="auto" sm="auto" className={classes.buttons}>
                  <Button
                    sx={{ margin: 3, marginLeft: 0 }}
                    variant="contained"
                    color="secondary"
                    onClick={submitChange}
                    style={{ width: 150 }}
                  >
                    {t('common.Save-button')}
                  </Button>
                </Grid>
                <Grid item xs="auto" sm="auto" className={classes.buttons}>
                  <Button
                    sx={{ margin: 3 }}
                    variant="contained"
                    color="primary"
                    onClick={resetChange}
                    style={{ marginLeft: 40, width: 150 }}
                  >
                    {t('common.Reset-button')}
                  </Button>
                </Grid>
                <Grid item xs="auto" sm="auto" className={classes.buttons}>
                  <Button
                    sx={{ margin: 3 }}
                    variant="contained"
                    color="primary"
                    onClick={cancelChange}
                    style={{ width: 150 }}
                  >
                    {t('common.Cancel-button')}
                  </Button>
                </Grid>
              </Grid>
            </Grid>
          </Grid>
        ) : (
          <Grid container spacing={0}>
            <Grid
              item
              xs={12}
              sm={12}
              md={12}
              lg={12}
              className={classes.content}
            >
              <Typography className={classes.typoAddTicket} variant="h6">
                {t('userGrid.Add User')}
              </Typography>
            </Grid>
            <Grid
              item
              xs={10}
              sm={10}
              md={10}
              lg={10}
              className={classes.content}
            >
              <Grid container spacing={0}>
                <Grid
                  item
                  xs={3}
                  sm={3}
                  md={3}
                  lg={3}
                  className={classes.paperInput}
                >
                  <form
                    onSubmit={(e) => {
                      submit(e);
                    }}
                  >
                    <TextField
                      label={t('common.Name')}
                      value={newName}
                      placeholder={t('common.Name')}
                      variant="outlined"
                      fullWidth
                      onChange={(ev) => {
                        setNewName(ev.target.value || '');
                      }}
                      InputProps={{
                        className: classes.input,
                      }}
                      InputLabelProps={{
                        className: classes.inputLabel,
                      }}
                    />
                  </form>
                </Grid>
                <Grid
                  item
                  xs={3}
                  sm={3}
                  md={3}
                  lg={3}
                  className={classes.paperInput}
                >
                  <form
                    onSubmit={(e) => {
                      submit(e);
                    }}
                  >
                    <TextField
                      label={t('userGrid.Pincode')}
                      value={newPincode}
                      variant="outlined"
                      autoComplete="false"
                      autoCorrect="false"
                      type="string"
                      required
                      error={
                        rootStore.userList.checkCode(newPincode) ||
                        newPincode.length !== 4
                      }
                      helperText={
                        newPincode.length !== 4
                          ? t('userGrid.Code to short')
                          : rootStore.userList.checkCode(newPincode)
                          ? t('userGrid.Code already used')
                          : 'Code OK'
                      }
                      fullWidth
                      onChange={(ev) => {
                        setNewPincode(ev.target.value);
                      }}
                      InputProps={{
                        className: classes.input,
                      }}
                      InputLabelProps={{
                        className: classes.inputLabel,
                        shrink: true,
                      }}
                    />
                  </form>
                </Grid>
                <Grid
                  item
                  xs={3}
                  sm={3}
                  md={3}
                  lg={3}
                  className={classes.paperInput}
                >
                  <TextField
                    variant="outlined"
                    label={t('common.level')}
                    value={newLevel}
                    placeholder={t('common.level')}
                    onChange={(ev) => {
                      setNewLevel(parseInt(ev.target.value) || 1);
                    }}
                    InputProps={{
                      className: classes.inputNumbers,
                    }}
                    InputLabelProps={{
                      className: classes.inputLabel,
                    }}
                  />
                </Grid>
                <Grid item xs={1} sm={1} className={classes.buttons}>
                  <Button
                    sx={{ margin: 3 }}
                    style={{ marginTop: -10, marginLeft: 10 }}
                    variant="contained"
                    color="secondary"
                    onClick={submit}
                  >
                    {t('common.Add-button')}
                  </Button>
                </Grid>
              </Grid>
            </Grid>
          </Grid>
        )}
      </Paper>
    </Paper>
  );
}

export default observer(Configuration);
