import DeleteIcon from "@mui/icons-material/Delete";
import VisibilityIcon from "@mui/icons-material/Visibility";
import {
  Button,
  IconButton,
  Paper,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Tooltip,
} from "@mui/material";
import { filesize } from "filesize";
import React from "react";
import { VMApi, VMInfo } from "../api/VMApi";
import { AsyncWidget } from "../widgets/AsyncWidget";
import { RouterLink } from "../widgets/RouterLink";
import { VirtWebRouteContainer } from "../widgets/VirtWebRouteContainer";
import { VMStatusWidget } from "../widgets/vms/VMStatusWidget";
import { useSnackbar } from "../hooks/providers/SnackbarProvider";
import { useConfirm } from "../hooks/providers/ConfirmDialogProvider";
import { useNavigate } from "react-router-dom";

export function VMListRoute(): React.ReactElement {
  const [list, setList] = React.useState<VMInfo[] | undefined>();

  const loadKey = React.useRef(1);

  const load = async () => {
    setList(await VMApi.GetList());
  };

  const reload = () => {
    loadKey.current += 1;
    setList(undefined);
  };

  return (
    <AsyncWidget
      loadKey={loadKey.current}
      errMsg="Failed to load Virtual Machines list!"
      load={load}
      ready={list !== undefined}
      build={() => (
        <VirtWebRouteContainer
          label="Virtual Machines"
          actions={
            <>
              <RouterLink to="/vms/new">
                <Button>New</Button>
              </RouterLink>
            </>
          }
        >
          <VMListWidget list={list!} onReload={reload} />
        </VirtWebRouteContainer>
      )}
    />
  );
}

function VMListWidget(p: {
  list: VMInfo[];
  onReload: () => void;
}): React.ReactElement {
  const confirm = useConfirm();
  const snackbar = useSnackbar();
  const navigate = useNavigate();

  const deleteVM = async (v: VMInfo) => {
    try {
      if (
        !(await confirm(
          `Do you really want to delete the vm ${v.name}? The operation CANNOT be undone!`,
          "Delete a VM",
          "DELETE"
        ))
      )
        return;

      const keepData = !(await confirm(
        "Do you want to delete the files of the VM?",
        "Delete a VM",
        "Delete the data",
        "keep the data"
      ));

      await VMApi.Delete(v, keepData);
      snackbar("The VM was successfully deleted!");

      p.onReload();
    } catch (e) {
      console.error(e);
      snackbar("Failed to delete VM!");
    }
  };

  return (
    <TableContainer component={Paper}>
      <Table>
        <TableHead>
          <TableRow>
            <TableCell>Name</TableCell>
            <TableCell>Description</TableCell>
            <TableCell>Memory</TableCell>
            <TableCell>Status</TableCell>
            <TableCell>Actions</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {p.list.map((row) => (
            <TableRow
              hover
              key={row.name}
              sx={{ "&:last-child td, &:last-child th": { border: 0 } }}
              onDoubleClick={() => navigate(row.ViewURL)}
            >
              <TableCell component="th" scope="row">
                {row.name}
              </TableCell>
              <TableCell>{row.description ?? ""}</TableCell>
              <TableCell>{filesize(row.memory * 1000 * 1000)}</TableCell>
              <TableCell>
                <VMStatusWidget vm={row} />
              </TableCell>
              <TableCell>
                <Tooltip title="View this VM">
                  <RouterLink to={row.ViewURL}>
                    <IconButton>
                      <VisibilityIcon />
                    </IconButton>
                  </RouterLink>
                </Tooltip>
                <Tooltip title="Delete this VM">
                  <IconButton onClick={() => deleteVM(row)}>
                    <DeleteIcon />
                  </IconButton>
                </Tooltip>
              </TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </TableContainer>
  );
}
