import React, { useState, useCallback } from "react";
import MachineTableRow from "./MachineTableRow";
import MachineAccordion from "./MachineAccordion";
import { ViewModes } from "../constants";
import { blip } from "../../../utils";
import { LastPage, RotateLeft, Launch, Stop } from "@mui/icons-material";
import { useTranslation } from "react-i18next";
import { endpoints } from "../../../utils/api";
import {
  Machine,
  MachineActionResult,
  MachineRestarted,
  MachineShutdown,
  RestartMachine,
  ShutdownMachine
} from "types";
import { Key, NetworkError, mutationFetcher, useGuardedMutation } from "units/swr";
import { usePingTrigger } from "../hooks";

type Props = {
  machine: Machine;
  viewMode: string;
};
const MachineContainer: React.FC<Props> = ({ machine, viewMode }) => {
  const [logs, setLogs] = useState<string[]>([]);
  const { t } = useTranslation();

  const addLog = useCallback(
    (text: string) => {
      setLogs(prev => [...prev, text]);
    },
    [setLogs]
  );

  const manageActionResponse = useCallback(
    (response: MachineActionResult) => {
      addLog(`Success: ${response.success}. Status: ${response.status}`);
      if (response.success) {
        blip.success(response.status);
      } else {
        blip.error(response.status);
      }
    },
    [addLog]
  );

  const { pingMachineTrigger } = usePingTrigger({
    onSuccess: manageActionResponse
  });

  const { trigger: shutdownMachineTrigger } = useGuardedMutation<MachineShutdown, NetworkError, Key, ShutdownMachine>(
    endpoints.network.machine.shutdown,
    mutationFetcher<ShutdownMachine>,
    {
      onSuccess: manageActionResponse
    }
  );

  const { trigger: restartMachineTrigger } = useGuardedMutation<MachineRestarted, NetworkError, Key, RestartMachine>(
    endpoints.network.machine.restart,
    mutationFetcher<RestartMachine>,
    {
      onSuccess: manageActionResponse
    }
  );

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

  const shutdownMachine = useCallback(
    async (machine: Machine) => shutdownMachineTrigger({ machineId: machine.machineId, delay: 0, force: false }),
    [shutdownMachineTrigger]
  );

  const restartMachine = useCallback(
    async (machine: Machine) => restartMachineTrigger({ machineId: machine.machineId, delay: 0, force: false }),
    [restartMachineTrigger]
  );

  const actions = [
    {
      code: "ping",
      effect: pingMachine,
      icon: LastPage,
      tooltip: t("Machine.Actions.Ping"),
      main: true
    },
    {
      code: "shutdown",
      effect: shutdownMachine,
      icon: Stop,
      tooltip: t("Machine.Actions.Shutdown"),
      main: false
    },
    {
      code: "restart",
      effect: restartMachine,
      icon: RotateLeft,
      tooltip: t("Machine.Actions.Restart"),
      main: false
    },
    {
      code: "advanced",
      effect: () => {
        // to do: implement
      },
      icon: Launch,
      tooltip: t("Machine.Actions.Advanced"),
      main: false
    }
  ];

  return (
    <>
      {viewMode === ViewModes.TABLE && (
        <MachineTableRow machine={machine} actions={actions} logs={logs} addLog={addLog} />
      )}
      {viewMode === ViewModes.ACCORDION && (
        <MachineAccordion machine={machine} actions={actions} logs={logs} addLog={addLog} />
      )}
    </>
  );
};

export default MachineContainer;
