import React, { useState, useEffect, useCallback } from "react";
import { IconButton, Tooltip } from "@mui/material";
import { PowerSettingsNew } from "@mui/icons-material";
import { useTranslation } from "react-i18next";
import { blip } from "../../../../utils";
import { msToMinAndSec } from "../../../../utils/time";
import { endpoints } from "../../../../utils/api";
import { Machine, MachineWaked, WakeMachine } from "types";
import { usePingTrigger } from "../../hooks";
import { Key, mutationFetcher, NetworkError, useSWRMutation } from "units/swr";

const initialState = { on: false };
const defaultPingInterval = 1200000; //20 minutes
const defaultStartingTime = 300000; //5 minutes

const pingInterval = parseInt(import.meta.env.VITE_APP_MACHINE_PING_INTERVAL ?? "") || defaultPingInterval;
const startingTime = parseInt(import.meta.env.VITE_APP_MACHINE_STARTING_TIME ?? "") || defaultStartingTime;

type Props = {
  machine: Machine;
  addLog: (message: string) => void;
  disabled: boolean;
};

const WakeComponent: React.FC<Props> = ({ machine, addLog, disabled }) => {
  const [state, setState] = useState(initialState);
  const [trigger, setTrigger] = useState(false);

  const { t } = useTranslation();

  const getCurrentDateTime = useCallback(() => {
    const currentDateTime = Date.now();
    const result = t("DATE_FORMAT", {
      date: { value: currentDateTime, format: "DD-MM-YYYY HH:mm:ss" }
    });
    return result;
  }, [t]);

  const log = useCallback(
    (message: string) => addLog(`[${getCurrentDateTime()}] ${message}`),
    [addLog, getCurrentDateTime]
  );

  const { pingMachineTrigger } = usePingTrigger({
    onSuccess: result => {
      setState(prev => ({ ...prev, on: result.success }));
      log(`[Ping]: Success: ${result.success}. Status: ${result.status}`);

      // trigger the next ping
      if (result.success) {
        setTimeout(() => {
          setTrigger(prev => !prev);
        }, pingInterval);
      }
    },
    onError: () => {
      // to do: handle error
    }
  });

  const { trigger: wakeMachineTrigger } = useSWRMutation<MachineWaked, NetworkError, Key, WakeMachine>(
    endpoints.network.machine.wake,
    mutationFetcher<WakeMachine>,
    {
      onError: err => blip.error(err.message),
      onSuccess: result => {
        setState(prev => ({ ...prev, on: result.success }));
        log(`[Wake]: Success: ${result.success}. Status: ${result.status}`);
        if (result.success) {
          blip.success(result.status);

          //retrigger
          log(`Periodic ping will be re-triggered in ${startingTime} ms [${msToMinAndSec(startingTime)}]`);
          setTimeout(() => {
            setTrigger(prev => !prev);
          }, startingTime);
        } else {
          blip.error(result.status);
        }
      }
    }
  );

  const pingMachine = useCallback(async () => {
    if (disabled) return;
    pingMachineTrigger({ machineId: machine.machineId });
  }, [machine.machineId, pingMachineTrigger, disabled]);

  useEffect(() => {
    pingMachine();
  }, [trigger, pingMachine]);

  const handleWakeClick = (event: React.MouseEvent<HTMLButtonElement>) => {
    wakeMachineTrigger({ machineId: machine.machineId });
    event.stopPropagation();
  };

  return (
    <Tooltip title={t(state.on ? "Machine.PoweredOn" : "Machine.Actions.Wake")}>
      <span>
        <IconButton
          id={`machine-${machine.machineId}-wake`}
          size={"small"}
          disabled={disabled || state.on}
          onClick={handleWakeClick}
          sx={{ padding: "0.2rem" }}
          style={state.on ? { color: "#33cc33" } : undefined}
          onFocus={event => event.stopPropagation()}
        >
          <PowerSettingsNew />
        </IconButton>
      </span>
    </Tooltip>
  );
};

export default WakeComponent;
