text: import React, { useState } from 'react';
  import { useSelector, useDispatch } from 'react-redux';
  import { addTransactionAction } from '../../redux/reducers/AuthReducer';
  import PropTypes from 'prop-types';
  import clsx from 'clsx';
  
  // Formating functions
  import NumberFormat from 'react-number-format';
  import { getCurrencySymbol } from '../../utils/getCurrencySymbol';
  
  // Material ui
  import {
    Grid,
    Container,
    MenuItem,
    Button,
    TextField,
    Chip,
    Switch
  } from '@material-ui/core';
  
  // Mui Date
  import {
    MuiPickersUtilsProvider,
    KeyboardDatePicker
  } from '@material-ui/pickers';
  import 'date-fns';
  import DateFnsUtils from '@date-io/date-fns';
  
  // Mui Stepper
  import Stepper from '@material-ui/core/Stepper';
  import Step from '@material-ui/core/Step';
  import StepLabel from '@material-ui/core/StepLabel';
  
  // Icons
  import Check from '@material-ui/icons/Check';
  import StepConnector from '@material-ui/core/StepConnector';
  import AccountBalanceIcon from '@material-ui/icons/AccountBalance';
  import AttachMoneyIcon from '@material-ui/icons/AttachMoney';
  import ClassIcon from '@material-ui/icons/Class';
  
  const currencies = ['JPY', 'EUR', 'USD'];
  
  const defaultExpenseCategories = [
    'Food',
    'Transportation',
    'Utility Bill',
    'Medical',
    'Savings',
    'Rent',
    'Clothing',
    'Necessaries',
    'Other'
  ];
  
  const defaultIncomeCategories = [
    'Salary',
    'Freelance Work',
    'Pocket Money',
    'Carried Over',
    'Other'
  ];
  
  const defaultWallets = ['Cash', 'German Bank', 'Japanese Bank'];
  
  function NumberFormatCustom(props) {
    const { inputRef, onChange, ...other } = props;
    return (
      <NumberFormat
        {...other}
        getInputRef={inputRef}
        onValueChange={(values) => {
          onChange({
            target: {
              name: props.name,
              value: parseFloat(values.value)
            }
          });
        }}
        thousandSeparator
        isNumericString
        prefix={`${props.currency} `}
      />
    );
  }
  
  const Step1 = ({ nextModal, setValues }) => {
    const [currentAmount, setCurrentAmount] = useState(null);
    const [currentCurrency, setCurrentCurrency] = useState('JPY');
    const [error, setError] = useState(false);
    const [currentDate, setCurrentDate] = useState(
      new Date(new Date().toJSON().slice(0, 10).replace(/-/g, '/'))
    );
  
    const buttonDisabled =
      typeof currentAmount !== 'number' || isNaN(currentAmount);
  
    const handleSubmit = async (name, value) => {
      const baseURL = 'https://api.frankfurter.app';
      const baseDate = currentDate.toJSON().slice(0, 10);
      const baseCurrency = currentCurrency;
      const targetCurrencies = currencies
        .filter((i) => i !== currentCurrency)
        .join();
  
      const url = `${baseURL}/${baseDate}?from=${baseCurrency}&to=${targetCurrencies}`;
  
      try {
        await fetch(url)
          .then(function (response) {
            if (response.status >= 400) {
              throw new Error('Bad response from server');
            }
            return response.json();
          })
          .then(function ({ rates }) {
            const objectDuplicate = { ...rates, [currentCurrency]: 1 };
            for (const [key, value] of Object.entries(objectDuplicate)) {
              objectDuplicate[key] = parseFloat(
                (value * currentAmount).toFixed(2)
              );
            }
            return objectDuplicate;
          })
          .then((data) =>
            setValues((previousState) => ({
              ...previousState,
              amount: data,
              [name]: value,
              date: new Date(currentDate).getTime()
            }))
          )
          .then(() => nextModal());
      } catch (error) {
        console.error("The exchange couldn't be fetched...", error);
        setError(true);
      }
    };
  
    return (
      <Container>
        <div className="p-4">
          {!error ? (
            <>
              <h5 className="font-size-xl mb-1 font-weight-bold text-center">
                Amount &amp; Type
              </h5>
              <p className="text-black-50 mb-4  text-center">
                Small section summary description can be added here!
              </p>
            </>
          ) : (
            <>
              <p className="text-black-50 mb-2  text-center">
                Please try again soon.
              </p>
              <h5 className="font-size-xl mb-3 font-weight-bold text-center">
                We are sorry the exchange rates for your other currencies couldn't
                be fetched.
              </h5>
            </>
          )}
  
          {!error && (
            <Grid container spacing={1} justify="center">
              <Grid item xs={10} className="d-flex justify-content-center my-2">
                <MuiPickersUtilsProvider utils={DateFnsUtils}>
                  <KeyboardDatePicker
                    style={{ margin: '0 auto' }}
                    disableToolbar
                    variant="inline"
                    format="yyyy/MM/dd"
                    margin="normal"
                    id="date"
                    label="Date"
                    name="date"
                    value={currentDate}
                    onChange={setCurrentDate}
                    KeyboardButtonProps={{
                      'aria-label': 'change date'
                    }}
                  />
                </MuiPickersUtilsProvider>
              </Grid>
              <Grid item xs={5}>
                <TextField
                  label="Amount"
                  value={currentAmount}
                  currency="true"
                  onChange={(e) => setCurrentAmount(e.target.value)}
                  name="amount"
                  autoComplete="off"
                  inputProps={{
                    currency: getCurrencySymbol(currentCurrency)
                  }}
                  id="amount"
                  InputProps={{
                    inputComponent: NumberFormatCustom
                  }}
                />
              </Grid>
              <Grid item xs={2}>
                <TextField
                  style={{ marginTop: '16px' }}
                  fullWidth
                  id="currency"
                  name="currency"
                  select
                  value={currentCurrency}
                  onChange={(e) => setCurrentCurrency(e.target.value)}>
                  {currencies.map((option) => (
                    <MenuItem key={option} name="currency" value={option}>
                      {`${getCurrencySymbol(option)}`}
                    </MenuItem>
                  ))}
                </TextField>
              </Grid>
              <Grid item xs={10}>
                <div className="rounded mt-4 p-4 d-flex align-items-center justify-content-around bg-secondary">
                  <Button
                    className="btn-primary font-weight-bold px-5"
                    value="Income"
                    name="type"
                    onClick={() => handleSubmit('type', 'Income')}
                    disabled={buttonDisabled}>
                    Income
                  </Button>
                  <Button
                    className="btn-primary font-weight-bold px-5"
                    disabled={buttonDisabled}
                    onClick={() => handleSubmit('type', 'Expense')}
                    value="Expense"
                    name="type">
                    Expense
                  </Button>
                </div>
              </Grid>
            </Grid>
          )}
        </div>
      </Container>
    );
  };
  const Step2 = ({ setValues, values, nextModal }) => {
    const [description, setDescription] = useState('');
  
    const categories =
      values.type === 'Expense'
        ? defaultExpenseCategories
        : defaultIncomeCategories;
  
    const handleSubmit = (value) => {
      setValues((previousState) => ({
        ...previousState,
        category: value,
        description
      }));
  
      nextModal();
    };
  
    return (
      <Container>
        <div className="p-4">
          <h5 className="font-size-xl mb-1 font-weight-bold text-center">
            Category &amp; Description
          </h5>
          <p className="text-black-50 mb-4  text-center">
            Small section summary description can be added here!
          </p>
          <Grid container spacing={1} justify="center">
            <Grid item xs={10}>
              <TextField
                label="Description"
                value={description}
                currency="true"
                fullWidth
                onChange={(e) => setDescription(e.target.value)}
                name="description"
                id="description"
                placeholder="Please enter some description..."
              />
            </Grid>
            <Grid
              item
              xs={10}
              className="my-3 d-flex justify-content-center flex-wrap">
              {categories.map((value) => (
                <Chip
                  key={value}
                  label={value}
                  name="category"
                  value={value}
                  disabled={description.length < 1}
                  className="mx-1 my-2 btn btn-primary"
                  onClick={() => handleSubmit(value)}
                />
              ))}
            </Grid>
          </Grid>
        </div>
      </Container>
    );
  };
  const Step3 = ({ setValues }) => {
    const [isActive, setIsActive] = useState(false);
  
    const handleSubmit = (value) => {
      setValues((prevState) => ({
        ...prevState,
        tax_relevant: isActive,
        wallet: value
      }));
    };
    return (
      <Container>
        <div className="p-4">
          <h5 className="font-size-xl mb-1 font-weight-bold text-center">
            Choose your account
          </h5>
          <Grid container>
            <Grid
              item
              xs={12}
              className="d-flex flex-row my-3 mx-3 align-items-center">
              <p className="text-black-50 m-0">
                Choose to make this transaction relevant for your tax declaration
                at the end of the year.
              </p>
              <Switch
                checked={isActive}
                onClick={() => setIsActive((prevState) => !prevState)}
                className="switch-medium toggle-switch-primary ml-4 mr-2"
              />
            </Grid>
            <Grid
              item
              xs={12}
              className="d-flex flex-row justify-content-center flex-wrap">
              {defaultWallets.map((value) => (
                <Button
                  key={value}
                  className="btn-primary font-weight-bold p-3 px-5 rounded m-2 font-size-md"
                  onClick={() => handleSubmit(value)}
                  value="Expense"
                  name="type">
                  {value}
                </Button>
              ))}
            </Grid>
          </Grid>
        </div>
      </Container>
    );
  };
  
  function StepIcon(props) {
    const { active, completed } = props;
  
    const icons = {
      1: <AttachMoneyIcon />,
      2: <ClassIcon />,
      3: <AccountBalanceIcon />
    };
  
    return (
      <div
        className={clsx(
          'd-50 transition-base d-flex align-items-center bg-gray-400 justify-content-center rounded',
          {
            'd-80 bg-primary text-white shadow-primary-sm': active,
            'd-50 bg-success text-white shadow-success-sm': completed
          }
        )}>
        {completed ? <Check className="completed" /> : icons[String(props.icon)]}
      </div>
    );
  }
  
  StepIcon.propTypes = {
    active: PropTypes.bool,
    completed: PropTypes.bool,
    icon: PropTypes.node
  };
  
  function getStepContent(step, setValues, values, handleNext) {
    switch (step) {
      case 0:
        return (
          <Step1 values={values} setValues={setValues} nextModal={handleNext} />
        );
      case 1:
        return (
          <Step2 values={values} setValues={setValues} nextModal={handleNext} />
        );
      case 2:
        return <Step3 setValues={setValues} />;
      default:
        return <Step1 />;
    }
  }
  
  export default function LivePreviewExample({ toggleDialog }) {
    // Redux
    const {
      user: { uid }
    } = useSelector((state) => state.auth);
    const dispatch = useDispatch();
  
    // Handle the stepper
    const [activeStep, setActiveStep] = useState(0);
    const steps = ['Amount', 'Category', 'Wallet'];
  
    const handleNext = () => {
      setActiveStep((prevActiveStep) => prevActiveStep + 1);
    };
  
    // Transaction info initial state
    const initialState = {
      amount: null,
      currency: currencies[0],
      type: '',
      description: '',
      category: '',
      wallet: '',
      date: null,
      tax_relevant: false
    };
  
    // Handle transaction information state
    const [values, setValues] = useState(initialState);
  
    const handleSuccess = () => {
      // Make asynchrous setState calls synchronous with promise
      Promise.resolve()
        .then(() => dispatch(addTransactionAction(uid, values))) // Dispatch the redux action
        .then(() => setValues(initialState)) // Reset values before useEffect runs again when closing the modal window
        .then(() => toggleDialog(false)); // Closing the window
    };
  
    // Trigger addTransaction Firestore when wallet value is valid
    React.useEffect(() => {
      if (values.wallet) {
        handleSuccess();
      }
    });
  
    return (
      <div>
        <div className="bg-secondary mb-3 pt-3">
          <Stepper
            className="stepper-horizontal-1"
            alternativeLabel
            activeStep={activeStep}
            connector={<StepConnector />}>
            {steps.map((label) => (
              <Step key={label}>
                <StepLabel StepIconComponent={StepIcon}>{label}</StepLabel>
              </Step>
            ))}
          </Stepper>
        </div>
        <div>
          <div>{getStepContent(activeStep, setValues, values, handleNext)}</div>
        </div>
      </div>
    );
  }
  