import { mdiHarddisk } from "@mdi/js";
import Icon from "@mdi/react";
import CheckCircleIcon from "@mui/icons-material/CheckCircle";
import DeleteIcon from "@mui/icons-material/Delete";
import {
  Avatar,
  Button,
  IconButton,
  ListItem,
  ListItemAvatar,
  ListItemText,
  Paper,
  Tooltip,
} from "@mui/material";
import { filesize } from "filesize";
import { ServerApi } from "../../api/ServerApi";
import { VMFileDisk, VMInfo } from "../../api/VMApi";
import { useConfirm } from "../../hooks/providers/ConfirmDialogProvider";
import { SelectInput } from "./SelectInput";
import { TextInput } from "./TextInput";

export function VMDisksList(p: {
  vm: VMInfo;
  onChange?: () => void;
  editable: boolean;
}): React.ReactElement {
  const addNewDisk = () => {
    p.vm.file_disks.push({
      format: "QCow2",
      size: 10000,
      delete: false,
      name: `disk${p.vm.file_disks.length}`,
      new: true,
    });
    p.onChange?.();
  };

  return (
    <>
      {/* disks list */}
      {p.vm.file_disks.map((d, num) => (
        <DiskInfo
          // eslint-disable-next-line react-x/no-array-index-key
          key={num}
          editable={p.editable}
          disk={d}
          onChange={p.onChange}
          removeFromList={() => {
            p.vm.file_disks.splice(num, 1);
            p.onChange?.();
          }}
        />
      ))}

      {p.editable && <Button onClick={addNewDisk}>Add new disk</Button>}
    </>
  );
}

function DiskInfo(p: {
  editable: boolean;
  disk: VMFileDisk;
  onChange?: () => void;
  removeFromList: () => void;
}): React.ReactElement {
  const confirm = useConfirm();
  const deleteDisk = async () => {
    if (p.disk.deleteType) {
      p.disk.deleteType = undefined;
      p.onChange?.();
      return;
    }

    const keepFile = await confirm(
      `You asked to delete the disk ${p.disk.name}. Do you want to keep the block file or not ? `,
      "Delete disk",
      "Keep the file",
      "Delete the file"
    );

    if (!(await confirm("Do you really want to delete this disk?"))) return;

    p.disk.deleteType = keepFile ? "keepfile" : "deletefile";
    p.onChange?.();
  };

  if (!p.editable || !p.disk.new)
    return (
      <ListItem
        secondaryAction={
          p.editable && (
            <IconButton
              edge="end"
              aria-label="delete disk"
              onClick={deleteDisk}
            >
              {p.disk.deleteType ? (
                <Tooltip title="Cancel disk removal">
                  <CheckCircleIcon />
                </Tooltip>
              ) : (
                <Tooltip title="Remove disk">
                  <DeleteIcon />
                </Tooltip>
              )}
            </IconButton>
          )
        }
      >
        <ListItemAvatar>
          <Avatar>
            <Icon path={mdiHarddisk} />
          </Avatar>
        </ListItemAvatar>
        <ListItemText
          primary={
            <>
              {p.disk.name}{" "}
              {p.disk.deleteType && (
                <span style={{ color: "red" }}>
                  {p.disk.deleteType === "deletefile"
                    ? "Remove, DELETING block file"
                    : "Remove, keeping block file"}
                </span>
              )}
            </>
          }
          secondary={`${filesize(p.disk.size * 1000 * 1000)} - ${
            p.disk.format
          }${p.disk.format == "Raw" ? " - " + p.disk.alloc_type : ""}`}
        />
      </ListItem>
    );

  return (
    <Paper elevation={3} style={{ margin: "10px", padding: "10px" }}>
      <div style={{ display: "flex", justifyContent: "space-between" }}>
        <TextInput
          editable={true}
          label="Disk name"
          size={ServerApi.Config.constraints.disk_name_size}
          checkValue={(v) => /^[a-zA-Z0-9]+$/.test(v)}
          value={p.disk.name}
          onValueChange={(v) => {
            p.disk.name = v ?? "";
            p.onChange?.();
          }}
        />
        <IconButton onClick={p.removeFromList}>
          <DeleteIcon />
        </IconButton>
      </div>

      <TextInput
        editable={true}
        label="Disk size (MB)"
        size={ServerApi.Config.constraints.disk_size}
        value={p.disk.size.toString()}
        onValueChange={(v) => {
          p.disk.size = Number(v ?? "0");
          p.onChange?.();
        }}
        type="number"
      />

      <SelectInput
        editable={true}
        label="Disk format"
        options={[
          { label: "Raw file", value: "Raw" },
          { label: "QCow2", value: "QCow2" },
        ]}
        value={p.disk.format}
        onValueChange={(v) => {
          p.disk.format = v as any;
          p.onChange?.();
        }}
      />

      {p.disk.format === "Raw" && (
        <SelectInput
          editable={true}
          label="File allocation type"
          options={[
            { label: "Sparse allocation", value: "Sparse" },
            { label: "Fixed allocation", value: "Fixed" },
          ]}
          value={p.disk.alloc_type}
          onValueChange={(v) => {
            if (p.disk.format === "Raw") p.disk.alloc_type = v as any;
            p.onChange?.();
          }}
        />
      )}
    </Paper>
  );
}
