/* eslint-disable react/jsx-props-no-spreading */
/* eslint-disable react/jsx-key */
/* eslint-disable radix */
/* eslint-disable @typescript-eslint/no-unused-expressions */
/* eslint-disable no-nested-ternary */
import React, { Dispatch, SetStateAction, useEffect } from 'react';
import { observer } from 'mobx-react';
import format from 'date-fns/format';
import {
  Button,
  Card,
  CardActions,
  CardContent,
  Divider,
  Grid,
  IconButton,
  Paper,
  TextField,
  Typography,
} from '@mui/material';
import { makeStyles } from '@mui/styles';

import AddShoppingCartIcon from '@mui/icons-material/AddShoppingCart';
import DeleteForeverIcon from '@mui/icons-material/DeleteForever';
import CreateIcon from '@mui/icons-material/Create';
import PrintIcon from '@mui/icons-material/Print';
import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker';
import { useNavigate } from 'react-router-dom';
import { add } from 'date-fns';
import { ipcRenderer } from 'electron';
import { useTranslation } from 'react-i18next';
import TicketModel from '../../models/Application/TicketModel';
import TicketList from '../../models/Application/TicketList';
import Ticket from '../../models/Application/Ticket';
import Basket from '../../models/Application/Basket';
import { getRootStore } from '../../models/root-store';

const useStyles = makeStyles({
  typoHeader: {
    marginLeft: -30,
    marginTop: 35,
    marginBottom: 25,
  },
  typo: {
    marginLeft: 25,
    marginTop: 25,
    marginBottom: 25,
  },
  content: {
    marginLeft: 0,
    marginTop: -15,
    marginBottom: 0,
  },
  delete: {
    display: 'flex',
    justifyContent: 'flex-end',
  },
  deleteButton: {
    margin: 0,
    padding: 0,
  },
  pos: {
    marginBottom: 5,
  },
  posCredits: {
    marginBottom: 10,
  },
  cardCredits: {
    marginTop: 5,
  },
  input: {
    color: 'white',
    fontSize: '1.1em',
    padding: '5px',
    width: 'auto',
  },
  inputLabel: {
    color: 'lightgrey',
    fontSize: '20px',
  },
  inputNumbers: {
    color: 'white',
    fontSize: '1.1em',
    padding: '5px',
    width: 'auto',
  },
  paperInput: {
    backgroundColor: '#666666',
    alignItems: 'center',
    paddingTop: 20,
    padding: 12,
    margin: 5,
    marginTop: -10,
    minHeight: 60,
  },
  cardAction: {
    display: 'block',
    textAlign: 'initial',
  },
});

const TicketView = observer(
  ({
    obj,
    onClickAmount,
    onRemove,
    selectedStartDate,
    handleStartDateChange,
    selectedEndDate,
    handleEndDateChange,
  }: {
    obj: TicketModel;
    onClickAmount(amount: number, directPrint: boolean): void;
    onRemove(): void;
    getDefaultStart: Date | number | null;
    getDefaultEnd: Date | number | null;
    selectedStartDate: Date | number | null;
    handleStartDateChange: Dispatch<SetStateAction<number | Date | null>>;
    selectedEndDate: Date | number | null;
    handleEndDateChange: Dispatch<SetStateAction<number | Date | null>>;
  }) => {
    const classes = useStyles();
    const useStyleBackground = makeStyles({
      root: {
        margin: 10,
        width: 300,
        maxWidth: 350,
        height: 'auto',
        maxHeight: 'auto',
        backgroundColor: obj.color,
      },
    });

    const backGroundColorCustom = useStyleBackground();
    const [newAmount, setNewAmount] = React.useState(obj.baseAmount);
    const [rootStore] = React.useState(() => getRootStore());

    const dateStart = new Date();
    dateStart.setHours(new Date(rootStore.ticketList.defaultStart).getHours());
    dateStart.setMinutes(
      new Date(rootStore.ticketList.defaultStart).getMinutes()
    );
    dateStart.setSeconds(0);
    const dateEnd = new Date();
    dateEnd.setHours(new Date(rootStore.ticketList.defaultEnd).getHours());
    dateEnd.setMinutes(new Date(rootStore.ticketList.defaultEnd).getMinutes());
    dateEnd.setSeconds(0);

    const totalAmount = () => {
      if (obj.baseAmount === 1 && newAmount === 1) {
        return <Typography variant="h6">€{obj.price}</Typography>;
      }
      if (newAmount === 1) {
        return <Typography variant="h6">€{obj.price}</Typography>;
      }
      if (newAmount === obj.baseAmount) {
        return (
          <Typography variant="h6">
            {obj.baseAmount} x €{obj.price} = €{obj.price * obj.baseAmount}
          </Typography>
        );
      }
      return (
        <Typography variant="h6">
          {newAmount} x €{obj.price} = €{obj.price * newAmount}
        </Typography>
      );
    };

    const { t } = useTranslation();
    return (
      <Grid key={obj.id} item>
        <Card
          sx={{
            margin: 10,
            width: 300,
            maxWidth: 350,
            height: 'auto',
            maxHeight: 'auto',
            backgroundColor: obj.color,
          }}
          variant="outlined"
        >
          <CardActions>
            <Grid
              container
              spacing={0}
              direction="row"
              alignItems="center"
              justifyContent="center"
              style={{
                marginTop: 5,
                marginLeft: 10,
                marginBottom: 0,
              }}
            >
              <Grid item xs={7}>
                {obj.price ? totalAmount() : null}
              </Grid>
              <Grid item xs={5}>
                {rootStore.userList.loggedInUser &&
                rootStore.userList.loggedInUser.userlevel <= 1 ? (
                  <>
                    <IconButton
                      onClick={() =>
                        rootStore.ticketList.setCurrentEdit(obj.id)
                      }
                      style={{
                        marginLeft: '0px',
                        backgroundColor: '#666666',
                        alignItems: 'center',
                      }}
                    >
                      <CreateIcon color="primary" fontSize="medium" />
                    </IconButton>
                    <IconButton
                      onClick={() => onRemove()}
                      style={{
                        marginLeft: '10px',
                        backgroundColor: '#666666',
                        color: '#FF2626',
                        alignItems: 'center',
                      }}
                    >
                      <DeleteForeverIcon fontSize="medium" />
                    </IconButton>
                  </>
                ) : null}
              </Grid>
            </Grid>
          </CardActions>
          <CardContent
            className={classes.content}
            onClick={() => {
              setNewAmount(obj.baseAmount);
              obj.startTimeConf !== 'Date & Time picker'
                ? rootStore.settings.printWithoutBasket
                  ? onClickAmount(newAmount, true)
                  : onClickAmount(newAmount, false)
                : setNewAmount(obj.baseAmount);
            }}
          >
            <Typography variant="h5" component="p">
              {obj.title}
            </Typography>
            <Typography className={classes.pos} color="textSecondary">
              {obj.subtitle}
            </Typography>
            <Divider className={classes.posCredits} />
            <Typography component="span" className={classes.cardCredits}>
              {t('addTicketModelView.Credits')}: {obj.credits}
            </Typography>
            {obj.startTimeConf === 'Date & Time picker' ? (
              <CardActions>
                <Typography
                  component="p"
                  style={{ marginLeft: -10, color: 'blue' }}
                  className={classes.cardCredits}
                >
                  {t('ticketModelListView.Start')}:
                </Typography>
                <DateTimePicker
                  ampm={false}
                  value={selectedStartDate}
                  onChange={handleStartDateChange}
                />
              </CardActions>
            ) : obj.startTimeConf === 'Start of day' ? (
              <Typography component="p" className={classes.cardCredits}>
                {t('ticketModelListView.Start')}:{' '}
                {t(`startTimeEnum.${obj.startTimeConf}`)}
              </Typography>
            ) : (
              <Typography component="p" className={classes.cardCredits}>
                {t('ticketModelListView.Start')}:{' '}
                {t(`startTimeEnum.${obj.startTimeConf}`)}
              </Typography>
            )}
            {obj.endTimeConf === 'Date & Time picker' ? (
              <CardActions>
                <Typography
                  component="p"
                  style={{ color: 'blue' }}
                  className={classes.cardCredits}
                >
                  {t('ticketModelListView.End')}:
                </Typography>
                <DateTimePicker
                  ampm={false}
                  value={selectedEndDate}
                  onChange={handleEndDateChange}
                />
              </CardActions>
            ) : obj.endTimeConf === 'Hours and minutes' ? (
              <>
                <Typography component="p" className={classes.cardCredits}>
                  {t('ticketModelListView.End')}:{' '}
                  {t(`endTimeEnum.${obj.endTimeConf}`)}
                </Typography>
                <Typography component="p" className={classes.cardCredits}>
                  {t('ticketModelListView.Validity')}:{' '}
                  {new Date(obj.endTimeValidity).getHours()}
                  {'h : '}
                  {new Date(obj.endTimeValidity).getMinutes()}m
                </Typography>
              </>
            ) : (
              <Typography component="p" className={classes.cardCredits}>
                {t('ticketModelListView.End')}:{' '}
                {t(`endTimeEnum.${obj.endTimeConf}`)}
              </Typography>
            )}
          </CardContent>
          <CardActions>
            {rootStore.settings.applicationMode === 0 ? (
              <Paper className={classes.paperInput}>
                <Grid
                  container
                  spacing={0}
                  direction="row"
                  alignItems="center"
                  justifyContent="space-around"
                >
                  <Grid item xs={4}>
                    <TextField
                      variant="outlined"
                      label={t('addTicketModelView.Amount')}
                      value={newAmount}
                      type="number"
                      onInput={(e) => {
                        (e.target as HTMLInputElement).value = Math.max(
                          1,
                          parseInt((e.target as HTMLInputElement).value)
                        )
                          .toString()
                          .slice(0, 12);
                      }}
                      onChange={(ev) => {
                        setNewAmount(parseInt(ev.target.value) || 0);
                      }}
                      InputProps={{
                        className: classes.inputNumbers,
                      }}
                      InputLabelProps={{
                        className: classes.inputLabel,
                      }}
                    />
                  </Grid>
                  <Grid item xs={2} />
                  <Grid item xs={4}>
                    {rootStore.settings.printWithoutBasket ? (
                      <Button
                        variant="contained"
                        color="secondary"
                        onClick={() => {
                          onClickAmount(newAmount, true);
                          setNewAmount(obj.baseAmount);
                        }}
                      >
                        <PrintIcon fontSize="large" />
                      </Button>
                    ) : (
                      <Button
                        variant="contained"
                        color="secondary"
                        onClick={() => {
                          onClickAmount(newAmount, false);
                          setNewAmount(obj.baseAmount);
                        }}
                      >
                        <AddShoppingCartIcon fontSize="large" />
                      </Button>
                    )}
                  </Grid>
                </Grid>
              </Paper>
            ) : null}
          </CardActions>
        </Card>
      </Grid>
    );
  }
);

const TicketModelListView = observer(
  ({ ticketList, basket }: { ticketList: TicketList; basket: Basket }) => {
    const classes = useStyles();
    const [rootStore] = React.useState(() => getRootStore());
    const [selectedStartDate, handleStartDateChange] = React.useState<
      Date | number | null
    >(new Date(rootStore.ticketList.defaultStart));
    const [selectedEndDate, handleEndDateChange] = React.useState<
      Date | number | null
    >(new Date(rootStore.ticketList.defaultEnd));

    const dateStart = new Date();
    dateStart.setHours(new Date(rootStore.ticketList.defaultStart).getHours());
    dateStart.setMinutes(
      new Date(rootStore.ticketList.defaultStart).getMinutes()
    );
    dateStart.setSeconds(0);

    const dateEnd = new Date();
    dateEnd.setHours(new Date(rootStore.ticketList.defaultEnd).getHours());
    dateEnd.setMinutes(new Date(rootStore.ticketList.defaultEnd).getMinutes());
    dateEnd.setSeconds(0);

    const [defaultStart, setDefaultStart] = React.useState<Date | number>(
      dateStart
    );
    const [defaultEnd, setDefaultEnd] = React.useState<Date | number>(dateEnd);

    const showTickets = (ticketmodelLevel: number) => {
      if (rootStore.userList.loggedInUser) {
        if (ticketmodelLevel >= rootStore.userList.loggedInUser.userlevel) {
          return true;
        }
        return false;
      }
      if (ticketmodelLevel >= rootStore.settings.ticketLevelToShow) {
        return true;
      }
      return false;
    };
    useEffect(() => {
      if (rootStore.ticketList.defaultStart !== defaultStart) {
        dateStart.setHours(
          new Date(rootStore.ticketList.defaultStart).getHours()
        );
        dateStart.setMinutes(
          new Date(rootStore.ticketList.defaultStart).getMinutes()
        );
        dateStart.setSeconds(0);
        setDefaultStart(dateStart);
      }
      if (rootStore.ticketList.defaultEnd !== defaultEnd) {
        dateEnd.setHours(new Date(rootStore.ticketList.defaultEnd).getHours());
        dateEnd.setMinutes(
          new Date(rootStore.ticketList.defaultEnd).getMinutes()
        );
        dateEnd.setSeconds(0);
        setDefaultEnd(dateEnd);
      }
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [rootStore.ticketList.defaultEnd, rootStore.ticketList.defaultStart]);

    useEffect(() => {
      ipcRenderer.on('workerDoneLoading', (event) => {
        basket.clear();
      });
      return () => {
        ipcRenderer.removeAllListeners('workerDoneLoading');
      };
    });
    const { t } = useTranslation();
    return (
      <>
        {ticketList.all.length > 0 ? (
          <></>
        ) : (
          <Typography
            className={classes.typoHeader}
            style={{ color: rootStore.settings.darkMode ? 'white' : 'black' }}
            variant="h4"
          >
            {t('ticketModelListView.No tickets')}
          </Typography>
        )}
        {ticketList.all.map((ticketmodel: TicketModel) =>
          showTickets(ticketmodel.userLevel) ? (
            <TicketView
              key={ticketmodel.id}
              obj={ticketmodel}
              selectedStartDate={selectedStartDate}
              handleStartDateChange={handleStartDateChange}
              selectedEndDate={selectedEndDate}
              handleEndDateChange={handleEndDateChange}
              getDefaultStart={defaultStart}
              getDefaultEnd={defaultEnd}
              onClickAmount={(amount: number, directPrint: boolean) => {
                if (rootStore.settings.applicationMode !== 0) return; // Check to see if we are not in lost ticket configure mode
                let i = 0;
                for (i = 0; i < amount; i += 1) {
                  basket.add(
                    new Ticket({
                      title: ticketmodel.title,
                      subtitle: ticketmodel.subtitle,
                      text: ticketmodel.text,
                      credits: ticketmodel.credits,
                      price: ticketmodel.price,
                      idTemplate: ticketmodel.idTemplate, // Only use last part of UUID, substring the rest
                      startTimeConf: ticketmodel.startTimeConf,
                      endTimeConf: ticketmodel.endTimeConf,
                      startTime:
                        typeof defaultStart === 'number'
                          ? '0'
                          : ticketmodel.startTimeConf === 'Start of day'
                          ? defaultStart.getTime().toString()
                          : '0',
                      endTime:
                        typeof defaultEnd === 'number'
                          ? '0'
                          : ticketmodel.endTimeConf === 'End of day'
                          ? defaultEnd.getTime().toString()
                          : '0',
                      startTimeTemp:
                        typeof selectedStartDate === 'number'
                          ? selectedStartDate
                          : selectedStartDate?.getTime() || 0,
                      endTimeTemp:
                        typeof selectedEndDate === 'number'
                          ? selectedEndDate
                          : selectedEndDate?.getTime() || 0,
                      endTimeValidity: ticketmodel.endTimeValidity,
                      color: ticketmodel.color,
                      idModel: ticketmodel.id,
                    })
                  );
                  handleEndDateChange(defaultEnd);
                  handleStartDateChange(defaultStart);
                }

                if (directPrint) {
                  const constructedArr = basket.all.map((ticket) => {
                    return ticket.returnAllJSON();
                  });
                  basket.clear();
                  ipcRenderer.postMessage(
                    'mainSendToPrint',
                    constructedArr,
                    []
                  );
                }
              }}
              onRemove={() => ticketList.remove(ticketmodel)}
            />
          ) : null
        )}
      </>
    );
  }
);

export default TicketModelListView;
