/* eslint-disable compat/compat */
/* eslint-disable radix */
import React, { useEffect, useState } from "react";
import { Grid, Paper, Typography, Fab, TextField } from "@mui/material";
import { makeStyles } from "@mui/styles";

import {
  compareAsc,
  differenceInSeconds,
  format,
  formatDistanceStrict,
  fromUnixTime,
} from "date-fns";
import { observer } from "mobx-react";
import { useNavigate } from "react-router-dom";
import ScannedTicket from "../../models/Application/ScannedTicket";
import Arrow from "../../assets/images/ArrowRightCAME200.png";
import PayOnFoot from "../../assets/images/PayOnFoot200.png";
import BasketView from "../views/BasketView";
import TicketModelListView from "../views/TicketModelListView";
import AddTicketModelView from "../views/AddTicketModelView";
import { getRootStore } from "../../models/root-store.ts";
import Tarif from "../../models/Application/Tarif";
import Template from "../../models/Application/Template";
import HomeContentTopPayOnFoot from "./HomeContentTopPayOnFoot";
import HomeContentTopVirtualPrinter from "./HomeContentTopVirtualPrinter";

const useStyles = makeStyles({
  paper: {
    alignItems: "center",
    padding: 10,
    marginTop: 10,
    margin: 20,
    marginBottom: 80,
    "@media print": {
      display: "none",
    },
  },
});
const succesFetch = false;
const tries = 0;

const HomeContentBottomVirtualPrinter = () => {
  const [rootStore] = useState(() => getRootStore());
  const classes = useStyles();
  const [qrTextField, setQrTextField] = useState<string>("");
  const [data, setData] = React.useState("No ticket scanned");
  const [state, setState] = React.useState("nothing");
  const [scannedTicket, setScannedTicket] = React.useState<ScannedTicket>();
  const [template, setTemplate] = React.useState<Template>();
  const [tarif, setTarif] = React.useState<Tarif>();
  const [startTime, setStartTime] = useState<Date>();
  const [endTime, setEndTime] = useState<Date>();
  const [time, setTime] = useState(format(new Date(), "HH:mm:ss - dd/MM/yyyy"));
  const [distance, setDistance] = React.useState("");
  const [distanceSeconds, setDistanceSeconds] = React.useState<number>();
  const [cancelState, setCancelState] = React.useState<boolean>(false);
  // const [errors, setErrors] = React.useState<number>(0);
  const [succesFetch, setSuccesFetch] = React.useState<boolean>(false);

  const history = useNavigate();

  const checkTime = () => {
    let localState = 0;
    if (endTime) {
      localState = compareAsc(new Date(), endTime);
    }
    setState(localState.toString());
  };

  const checkDistanceWords = () => {
    let localDistance = "";
    if (endTime) {
      localDistance = formatDistanceStrict(new Date(), endTime);
    }
    setDistance(localDistance);
  };

  const checkPay = async () => {
    let localDistanceSeconds = 0;
    if (!endTime) {
      return;
    }
    localDistanceSeconds = differenceInSeconds(new Date(), endTime);
    setDistanceSeconds(localDistanceSeconds);
    let localPriceToPay;
    if (tarif) {
      localPriceToPay = await tarif.priceToPay(localDistanceSeconds);
    }
    if (typeof localPriceToPay === "number" && localPriceToPay !== -1) {
      rootStore.ui.setPriceToPay(localPriceToPay);
    } else {
      rootStore.ui.setPriceToPay(-1);
    }
  };

  const handleDecode = (result: any) => {
    // Checks
    if (result === null) {
      return;
    }
    let dataJSON;
    if (result) {
      try {
        dataJSON = JSON.parse(result);
      } catch (e) {
        console.log(e); // error in the above string (in this case, yes)!
        rootStore.settings.setSerialMessage("");
        return;
      }
    }
    if (
      !dataJSON[0] &&
      !dataJSON[1] &&
      !dataJSON[2] &&
      !dataJSON[3] &&
      !dataJSON[4] &&
      !dataJSON[5] &&
      !dataJSON[6] &&
      !dataJSON[7]
    ) {
      return;
    }
    // Set local state
    setQrTextField("");
    rootStore.ui.setLostTicketMode(false);
    rootStore.ui.setViewDetail(false);

    const localScannedTicket = new ScannedTicket({
      idTicket: parseInt(dataJSON[0]),
      version: parseInt(dataJSON[1]),
      startType: parseInt(dataJSON[2]),
      startTime: parseInt(dataJSON[3]),
      endType: parseInt(dataJSON[4]),
      endTime: parseInt(dataJSON[5]),
      credits: parseInt(dataJSON[6]),
      check: dataJSON[7],
      qrData: dataJSON.toString(),
    });
    setData(localScannedTicket.returnSignedString());

    rootStore.scannedTicketList.add(localScannedTicket);
    setScannedTicket(localScannedTicket);
    const localTemplateId =
      rootStore.templateList.returnTemplateForTicket(localScannedTicket);
    const localTemplate =
      rootStore.templateList.getTemplateById(localTemplateId);
    setTemplate(localTemplate);
    if (localTemplate) {
      setTarif(rootStore.tarifList.getTarifById(localTemplate.idTarif));
    }

    if (typeof parseInt(dataJSON[3]) === "number") {
      setStartTime(new Date(fromUnixTime(parseInt(dataJSON[3]))));
    }

    let localState = 0;
    if (typeof parseInt(dataJSON[5]) === "number") {
      setEndTime(new Date(fromUnixTime(parseInt(dataJSON[5]))));
      localState = compareAsc(
        new Date(),
        new Date(fromUnixTime(parseInt(dataJSON[5])))
      );
    }
    setState(localState.toString());
  };

  useEffect(() => {
    if (rootStore.settings.serialMessage !== qrTextField) {
      setQrTextField(rootStore.settings.serialMessage);
      handleDecode(rootStore.settings.serialMessage);
      checkPay();
      rootStore.settings.setSerialMessage("");
    }
    return () => {};
  }, [rootStore.settings.serialMessage]);

  useEffect(() => {
    if (rootStore.ui.priceToPay === -1) {
      setEndTime(undefined);
    }
    return () => {};
  }, [rootStore.ui.priceToPay]);

  useEffect(() => {
    const interval = setInterval(() => {
      setTime(format(new Date(), "HH:mm:ss - dd/MM/yyyy"));
      checkTime();
      checkPay();
      checkDistanceWords();
    }, 1000);
    return () => {
      clearInterval(interval);
    };
  });

  const showStartTime = () => {
    let newDateObject;
    if (typeof scannedTicket?.startTime === "number") {
      newDateObject = format(
        new Date(fromUnixTime(scannedTicket?.startTime)),
        "HH:mm:ss-dd/MM/yyyy"
      );
    }
    if (typeof newDateObject === "undefined") {
      newDateObject = "no valid date";
    }
    return newDateObject;
  };

  const showEndTime = () => {
    let newDateObject;
    if (typeof scannedTicket?.endTime === "number") {
      newDateObject = format(
        new Date(fromUnixTime(scannedTicket?.endTime)),
        "HH:mm:ss-dd/MM/yyyy"
      );
    }
    if (typeof newDateObject === "undefined") {
      newDateObject = "no valid date";
    }
    return newDateObject;
  };

  const fetchWithTimeout = async (
    url: string,
    timeout: number,
    retries: number
  ) => {
    const ctrl = new AbortController();
    const { signal } = ctrl;
    console.log(`${url} ${retries}`);

    const fetchData: any = fetch(url, { signal })
      .then((response) => {
        // exclude 4xx and 5xx status codes
        if (response.status >= 200 && response.status <= 299) {
          return response.json();
        }
        if (retries > 0) {
          return fetchWithTimeout(url, timeout, retries - 1);
        }
        throw new Error(response.status.toString());
      })
      .then((json) => json)
      .catch((error) => {
        throw error;
      }); // sent error stack trace
    // set timeout
    const timeOut = new Promise((resolve, reject) => {
      setTimeout(async () => {
        ctrl.abort(); // abort fetch request
        return reject(Error());
      }, timeout);
    });

    try {
      const result = await Promise.race([fetchData, timeOut]);
      return result;
    } catch (err) {
      if (retries > 0) {
        return fetchWithTimeout(url, timeout, retries - 1);
      }
    }
  };

  return (
    <>
      {rootStore.basket.amount && !rootStore.settings.printWithoutBasket ? (
        <Grid item xs={12}>
          <Paper
            elevation={3}
            className={classes.paper}
            style={{ background: "#61728E85" }}
          >
            <Grid container justifyContent="center" spacing={0}>
              <BasketView basket={rootStore.basket} />
            </Grid>
          </Paper>
        </Grid>
      ) : null}
    </>
  );
};

export default observer(HomeContentBottomVirtualPrinter);
