/* eslint-disable react/jsx-key */
/* eslint-disable radix */
/* eslint-disable react/jsx-props-no-spreading */
import React, { useEffect, useState } from 'react';
import { observer } from 'mobx-react';

import {
  FormControl,
  Grid,
  Paper,
  Typography,
  TextField,
  Button,
  Autocomplete,
} from '@mui/material';
import { makeStyles } from '@mui/styles';

import { Color, ColorPicker, ColorValue } from 'mui-color';
import NumberFormat from 'react-number-format';
import { draft } from 'mobx-keystone';
import { TimePicker } from '@mui/x-date-pickers/TimePicker';
import { useTranslation } from 'react-i18next';
import TicketModel from '../../models/Application/TicketModel';
import TicketList from '../../models/Application/TicketList';
import Basket from '../../models/Application/Basket';

import endTimeEnum from '../../constants/endTimeEnum';
import startTimeEnum from '../../constants/startTimeEnum';
import { getRootStore } from '../../models/root-store';

interface NumberFormatPriceProps {
  inputRef: (instance: NumberFormat | null) => void;
  onChange: (event: { target: { name: string; value: string } }) => void;
  name: string;
}

function NumberFormatPrice(props: NumberFormatPriceProps) {
  const { inputRef, onChange, ...other } = props;

  return (
    <NumberFormat
      {...other}
      getInputRef={inputRef}
      onValueChange={(values) => {
        onChange({
          target: {
            name: props.name,
            value: values.value,
          },
        });
      }}
      thousandSeparator
      fixedDecimalScale
      decimalScale={2}
      prefix="€"
    />
  );
}
interface NumberFormatCreditsProps {
  inputRef: (instance: NumberFormat | null) => void;
  onChange: (event: { target: { name: string; value: string } }) => void;
  name: string;
}

function NumberFormatCredits(props: NumberFormatCreditsProps) {
  const { inputRef, onChange, ...other } = props;

  return (
    <NumberFormat
      {...other}
      getInputRef={inputRef}
      onValueChange={(values) => {
        onChange({
          target: {
            name: props.name,
            value: values.value,
          },
        });
      }}
      thousandSeparator
      fixedDecimalScale
      decimalScale={2}
    />
  );
}

const AddTicketModelView = observer(
  ({ ticketList, basket }: { ticketList: TicketList; basket: Basket }) => {
    const { t } = useTranslation();
    const [rootStore] = React.useState(() => getRootStore());
    const [newTicketTitle, setNewTicketTitle] = React.useState('Parking');
    const [newTicketSubtitle, setNewTicketSubtitle] =
      React.useState('Parking ticket');
    const [newTicketText, setNewTicketText] = React.useState(
      'Please scan this ticket at the exit'
    );
    const [newTicketPrice, setNewTicketPrice] = React.useState('10.00');
    const [newTicketCredits, setNewTicketCredits] = React.useState('1.00');
    const [newTicketLevel, setNewTicketLevel] = React.useState(1);
    const [newStartTimeConf, setNewStartTimeConf] = React.useState(
      startTimeEnum[0].label
    );
    const [newEndTimeConf, setNewEndTimeConf] = React.useState(
      endTimeEnum[0].label
    );
    const [newBaseAmount, setNewBaseAmount] = React.useState(1);
    const [color, setColor] = useState('#95a5a6');
    const [ticketModelDraft, setTicketModelDraft] = useState<any>();
    const [editMode, setEditMode] = useState<boolean>(false);
    const dateValidity = new Date();
    dateValidity.setHours(0);
    dateValidity.setMinutes(30);
    dateValidity.setSeconds(0);
    const [selectedTime, setSelectedTime] = React.useState<number | null>(
      dateValidity.getTime()
    );

    const defaultValueIdTemplate = rootStore.templateList.all[0]
      ? rootStore.templateList.all[0].id
      : '0';

    const [newIdTemplate, setNewIdTemplate] = React.useState(
      defaultValueIdTemplate
    );

    const palette = {
      dodgergrey: '#95a5a6',
      gray: 'gray',
      green: '#00ff00',
      yellow: 'yellow',
      orange: 'orange',
      purple: 'purple',
      white: 'white',
      blue: '#0000ff',
      dodgerblue: 'dodgerblue',
      cameblue: '#009fe2',
    };

    const useStyles = makeStyles({
      content: {
        alignItems: 'center',
      },
      paperInput: {
        backgroundColor: '#666666',
        alignItems: 'center',
        paddingTop: 15,
        padding: 10,
        margin: 3,
        minHeight: 70,
      },
      buttonInput: {
        backgroundColor: '#666666',
        alignItems: 'center',
        justifyContent: 'center',
        padding: 12,
        margin: 5,
      },
      title: {
        fontSize: 14,
      },
      typo: {
        marginLeft: 25,
        marginTop: 25,
        marginBottom: 25,
      },
      typoAddTicket: {
        marginLeft: 25,
        marginRight: 25,
        marginTop: 25,
        marginBottom: 25,
      },
      label: {
        padding: 15,
      },
      button: {
        padding: 3,
      },
      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',
      },
      delete: {
        display: 'flex',
        justifyContentContent: 'flex-end',
      },
      buttons: {
        alignItems: 'center',
        alignSelf: 'center',
        textAlign: 'center',
        padding: 0,
        margin: 0,
        minHeight: 0,
      },
    });

    const classes = useStyles();

    useEffect(() => {
      if (rootStore.ticketList.currentEdit !== '0') {
        setEditMode(true);
        const elementPos = rootStore.ticketList.all
          .map(function (tic: TicketModel) {
            return tic.id;
          })
          .indexOf(rootStore.ticketList.currentEdit);
        if (elementPos === -1) {
          rootStore.ticketList.setCurrentEdit('0');
        }
        const ticketModelDraftTemp = draft(
          rootStore.ticketList.all[elementPos]
        );
        setTicketModelDraft(ticketModelDraftTemp);
        setNewTicketTitle(ticketModelDraftTemp.data.title);
        setNewTicketSubtitle(ticketModelDraftTemp.data.subtitle);
        setNewTicketText(ticketModelDraftTemp.data.text);
        setNewTicketPrice(ticketModelDraftTemp.data.price.toString());
        setNewTicketCredits(ticketModelDraftTemp.data.credits.toString());
        setNewStartTimeConf(ticketModelDraftTemp.data.startTimeConf);
        setNewEndTimeConf(ticketModelDraftTemp.data.endTimeConf);
        setSelectedTime(ticketModelDraftTemp.data.endTimeValidity);
        setNewTicketLevel(ticketModelDraftTemp.data.userLevel);
        setNewBaseAmount(ticketModelDraftTemp.data.baseAmount);
        setNewIdTemplate(ticketModelDraftTemp.data.idTemplate);
        setColor(ticketModelDraftTemp.data.color);
      }
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [rootStore.ticketList.currentEdit]);

    /*
    const handleChangeColor = (newValue: Color) => {
      setColor(`#${newValue.hex}`.toString());
    };
    */

    const handleChangeColor = (newValue: ColorValue) => {
      // Below is correct, it should contain .hex
      // @ts-ignore: Unreachable code error
      setColor(`#${newValue.hex}`);
    };
    const submitChange = (e: any) => {
      e.preventDefault();
      ticketModelDraft.data.change(
        newTicketTitle,
        newTicketSubtitle,
        newTicketText,
        parseFloat(newTicketPrice),
        parseFloat(newTicketCredits),
        newStartTimeConf,
        newEndTimeConf,
        selectedTime,
        newTicketLevel,
        newBaseAmount,
        color,
        newIdTemplate
      );
      ticketModelDraft.commit();
      setTicketModelDraft(undefined);
      setNewTicketTitle('Parking');
      setNewTicketSubtitle('Parking ticket');
      setNewTicketText('Please scan this ticket at the exit');
      setNewTicketPrice('10.00');
      setNewTicketCredits('1.00');
      setNewStartTimeConf(startTimeEnum[0].label);
      setNewEndTimeConf(endTimeEnum[0].label);
      setSelectedTime(dateValidity.getTime());
      setNewTicketLevel(1);
      setNewBaseAmount(1);
      setNewIdTemplate(defaultValueIdTemplate);
      rootStore.ticketList.setCurrentEdit('0');
      setEditMode(false);
    };

    const cancelChange = () => {
      ticketModelDraft.reset();
      setTicketModelDraft(undefined);
      setNewTicketTitle('Parking');
      setNewTicketSubtitle('Parking ticket');
      setNewTicketText('Please scan this ticket at the exit');
      setNewTicketPrice('10.00');
      setNewTicketCredits('1.00');
      setNewStartTimeConf(startTimeEnum[0].label);
      setNewEndTimeConf(endTimeEnum[0].label);
      setSelectedTime(dateValidity.getTime());
      setNewTicketLevel(1);
      setNewBaseAmount(1);
      setNewIdTemplate(defaultValueIdTemplate);
      rootStore.ticketList.setCurrentEdit('0');
      setEditMode(false);
    };

    const resetChange = () => {
      ticketModelDraft.reset();
      setNewTicketTitle(ticketModelDraft.data.title);
      setNewTicketSubtitle(ticketModelDraft.data.subtitle);
      setNewTicketText(ticketModelDraft.data.text);
      setNewTicketPrice(ticketModelDraft.data.price.toString());
      setNewTicketCredits(ticketModelDraft.data.credits.toString());
      setNewStartTimeConf(ticketModelDraft.data.startTimeConf);
      setNewEndTimeConf(ticketModelDraft.data.endTimeConf);
      setSelectedTime(ticketModelDraft.data.endTimeValidity);
      setNewTicketLevel(ticketModelDraft.data.userLevel);
      setNewBaseAmount(ticketModelDraft.data.baseAmount);
      setNewIdTemplate(ticketModelDraft.data.idTemplate);
      setColor(ticketModelDraft.data.color);
    };

    const submit = (e: any) => {
      e.preventDefault();
      ticketList.add(
        new TicketModel({
          idTemplate: newIdTemplate,
          title: newTicketTitle,
          subtitle: newTicketSubtitle,
          text: newTicketText,
          price: parseFloat(newTicketPrice),
          credits: parseFloat(newTicketCredits),
          startTimeConf: newStartTimeConf,
          endTimeConf: newEndTimeConf,
          endTimeValidity: selectedTime || new Date().getTime(),
          userLevel: newTicketLevel,
          baseAmount: newBaseAmount,
          color,
        })
      );
      setNewTicketTitle('Parking');
      setNewTicketSubtitle('Parking ticket');
      setNewTicketText('Please scan this ticket at the exit');
      setNewTicketPrice('10.00');
      setNewTicketCredits('1.00');
      setNewStartTimeConf(startTimeEnum[0].label);
      setNewEndTimeConf(endTimeEnum[0].label);
      setSelectedTime(dateValidity.getTime());
      setNewTicketLevel(1);
      setNewBaseAmount(1);
      setNewIdTemplate(defaultValueIdTemplate);
    };

    return (
      <Grid container spacing={0}>
        <Grid item xs={12} sm={12} md={2} lg={2} className={classes.content}>
          <Typography
            className={classes.typoAddTicket}
            style={{ color: rootStore.settings.darkMode ? 'white' : 'black' }}
            variant="h4"
          >
            {editMode
              ? 'Modify Ticket:'
              : t('addTicketModelView.Add Ticket model')}
          </Typography>
        </Grid>
        <Grid item xs={10} sm={10} md={10} lg={10} className={classes.content}>
          <Grid container spacing={0}>
            <Grid item xs={12} sm={12} md={6} lg={3}>
              <Paper className={classes.paperInput}>
                <form
                  onSubmit={(e) => {
                    submit(e);
                  }}
                >
                  <TextField
                    label={t('addTicketModelView.Title')}
                    value={newTicketTitle}
                    placeholder={t('addTicketModelView.Title')}
                    variant="outlined"
                    fullWidth
                    onChange={(ev) => {
                      setNewTicketTitle(ev.target.value || '');
                    }}
                    InputProps={{
                      className: classes.input,
                    }}
                    InputLabelProps={{
                      className: classes.inputLabel,
                    }}
                  />
                </form>
              </Paper>
            </Grid>
            <Grid item xs={12} sm={12} md={6} lg={3}>
              <Paper className={classes.paperInput}>
                <TextField
                  variant="outlined"
                  label={t('addTicketModelView.Subtitle')}
                  value={newTicketSubtitle}
                  placeholder={t('addTicketModelView.Subtitle')}
                  fullWidth
                  onChange={(ev) => {
                    setNewTicketSubtitle(ev.target.value || '');
                  }}
                  InputProps={{
                    className: classes.input,
                  }}
                  InputLabelProps={{
                    className: classes.inputLabel,
                  }}
                />
              </Paper>
            </Grid>
            <Grid item xs={12} sm={12} md={6} lg={4}>
              <Paper className={classes.paperInput}>
                <FormControl fullWidth variant="outlined">
                  <TextField
                    variant="outlined"
                    label={t('addTicketModelView.Text')}
                    value={newTicketText}
                    placeholder={t('addTicketModelView.Text')}
                    fullWidth
                    onChange={(ev) => {
                      setNewTicketText(ev.target.value || '');
                    }}
                    InputProps={{
                      className: classes.input,
                    }}
                    InputLabelProps={{
                      className: classes.inputLabel,
                    }}
                  />
                </FormControl>
              </Paper>
            </Grid>
            <Grid item xs={6} sm={6} md={2} lg={2}>
              <Paper className={classes.paperInput}>
                <TextField
                  variant="outlined"
                  label={t('addTicketModelView.Credits')}
                  value={newTicketCredits}
                  placeholder={t('addTicketModelView.Credits')}
                  onChange={(ev) => {
                    setNewTicketCredits(ev.target.value || '1.00');
                  }}
                  InputProps={{
                    className: classes.inputNumbers,
                  }}
                  InputLabelProps={{
                    className: classes.inputLabel,
                    shrink: true,
                  }}
                />
              </Paper>
            </Grid>
            <Grid item xs={12} sm={6} md={4} lg={3}>
              <Paper className={classes.paperInput}>
                <Autocomplete
                  id="Mode"
                  defaultValue={startTimeEnum[0]}
                  options={startTimeEnum}
                  getOptionLabel={(option) => option.label}
                  onChange={(_event: any, newValue: any) => {
                    setNewStartTimeConf(newValue.label);
                  }}
                  selectOnFocus
                  clearOnBlur
                  disableClearable
                  renderInput={(params) => (
                    <TextField
                      {...params}
                      label={t('addTicketModelView.Start time configuration')}
                      variant="outlined"
                    />
                  )}
                />
              </Paper>
            </Grid>
            <Grid item xs={12} sm={12} md={4} lg={3}>
              <Paper className={classes.paperInput}>
                <Autocomplete
                  id="Mode"
                  defaultValue={endTimeEnum[0]}
                  options={endTimeEnum}
                  getOptionLabel={(option) => option.label}
                  onChange={(_event: any, newValue: any) => {
                    setNewEndTimeConf(newValue.label);
                  }}
                  selectOnFocus
                  clearOnBlur
                  disableClearable
                  renderInput={(params) => (
                    <TextField
                      {...params}
                      label={t('addTicketModelView.End time configuration')}
                      variant="outlined"
                    />
                  )}
                />
              </Paper>
            </Grid>
            {newEndTimeConf === 'Hours and minutes' ? (
              <Grid item xs={6} sm={6} md={4} lg={2}>
                <Paper className={classes.paperInput}>
                  <FormControl fullWidth variant="outlined">
                    <TimePicker
                      ampm={false}
                      value={selectedTime}
                      onChange={(date) => {
                        setSelectedTime(date?.getTime() || 0);
                      }}
                    />
                  </FormControl>
                </Paper>
              </Grid>
            ) : null}
            <Grid item xs={6} sm={6} md={2} lg={2}>
              <Paper className={classes.paperInput}>
                <FormControl fullWidth variant="outlined">
                  <TextField
                    variant="outlined"
                    label={t('addTicketModelView.Price')}
                    value={newTicketPrice}
                    onChange={(ev) => {
                      setNewTicketPrice(ev.target.value || '1.00');
                    }}
                    InputProps={{
                      className: classes.inputNumbers,
                    }}
                    InputLabelProps={{
                      className: classes.inputLabel,
                      shrink: true,
                    }}
                  />
                </FormControl>
              </Paper>
            </Grid>
            <Grid item xs={6} sm={6} md={2} lg={2}>
              <Paper className={classes.paperInput}>
                <TextField
                  variant="outlined"
                  label={t('common.level')}
                  value={newTicketLevel}
                  placeholder={t('common.level')}
                  onChange={(ev) => {
                    setNewTicketLevel(parseInt(ev.target.value) || 1);
                  }}
                  InputProps={{
                    className: classes.inputNumbers,
                  }}
                  InputLabelProps={{
                    className: classes.inputLabel,
                  }}
                />
              </Paper>
            </Grid>
            <Grid item xs={6} sm={6} md={2} lg={2}>
              <Paper className={classes.paperInput}>
                <TextField
                  variant="outlined"
                  label={t('addTicketModelView.Amount')}
                  value={newBaseAmount}
                  onInput={(e) => {
                    (e.target as HTMLInputElement).value = Math.max(
                      1,
                      parseInt((e.target as HTMLInputElement).value)
                    )
                      .toString()
                      .slice(0, 12);
                  }}
                  onChange={(ev) => {
                    setNewBaseAmount(parseInt(ev.target.value) || 1);
                  }}
                  InputProps={{
                    className: classes.inputNumbers,
                  }}
                  InputLabelProps={{
                    className: classes.inputLabel,
                  }}
                />
              </Paper>
            </Grid>
            <Grid item xs={6} sm={6} md={2} lg={2}>
              <Paper className={classes.paperInput}>
                <Autocomplete
                  disabled={rootStore.templateList.all.length === 0}
                  options={rootStore.templateList.all}
                  value={
                    typeof rootStore.templateList.getTemplateById(
                      newIdTemplate
                    ) === 'undefined'
                      ? rootStore.templateList.all[0]
                      : rootStore.templateList.getTemplateById(newIdTemplate)
                  }
                  disableClearable
                  renderOption={(props, option) => {
                    return (
                      <li {...props} key={option.id}>
                        {option.name}
                      </li>
                    );
                  }}
                  getOptionLabel={(option) => option.name}
                  onChange={(_event: any, newValue: any) => {
                    setNewIdTemplate(newValue.id);
                  }}
                  renderInput={(params) => (
                    <TextField
                      {...params}
                      label={
                        rootStore.templateList.all.length !== 0
                          ? t('Template key')
                          : 'No template key'
                      }
                      variant="outlined"
                    />
                  )}
                />
              </Paper>
            </Grid>
            <Grid item xs={3} sm={3} md={2} lg={1}>
              <Paper className={classes.paperInput}>
                <Typography variant="body1" component="span">
                  {t('addTicketModelView.Color')}
                  <ColorPicker
                    palette={palette}
                    value={color}
                    onChange={handleChangeColor}
                    hideTextfield
                  />
                </Typography>
              </Paper>
            </Grid>
            {editMode ? (
              <>
                <Grid item xs="auto" className={classes.buttons}>
                  <Paper className={classes.buttonInput}>
                    <Button
                      variant="contained"
                      color="secondary"
                      onClick={submitChange}
                    >
                      {t('common.Save-button')}
                    </Button>
                  </Paper>
                </Grid>
                <Grid item xs="auto" className={classes.buttons}>
                  <Paper className={classes.buttonInput}>
                    <Button
                      variant="contained"
                      color="primary"
                      onClick={resetChange}
                    >
                      {t('common.Reset-button')}
                    </Button>
                  </Paper>
                </Grid>
                <Grid item xs="auto" className={classes.buttons}>
                  <Paper className={classes.buttonInput}>
                    <Button
                      variant="contained"
                      color="primary"
                      onClick={cancelChange}
                    >
                      {t('common.Cancel-button')}
                    </Button>
                  </Paper>
                </Grid>
              </>
            ) : (
              <Grid item xs="auto" className={classes.buttons}>
                <Paper className={classes.buttonInput}>
                  <Button
                    variant="contained"
                    color="secondary"
                    onClick={submit}
                  >
                    + {t('addTicketModelView.Add ticket')}
                  </Button>
                </Paper>
              </Grid>
            )}
          </Grid>
        </Grid>
      </Grid>
    );
  }
);

export default AddTicketModelView;
