import {
  Tooltip,
  IconButton,
  Paper,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
} from "@mui/material";
import React from "react";
import { Device, DeviceApi } from "../api/DeviceApi";
import { AsyncWidget } from "../widgets/AsyncWidget";
import { SolarEnergyRouteContainer } from "../widgets/SolarEnergyRouteContainer";
import RefreshIcon from "@mui/icons-material/Refresh";
import { TimeWidget } from "../widgets/TimeWidget";
import DeleteIcon from "@mui/icons-material/Delete";
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
import { useConfirm } from "../hooks/context_providers/ConfirmDialogProvider";
import { useLoadingMessage } from "../hooks/context_providers/LoadingMessageProvider";
import { useSnackbar } from "../hooks/context_providers/SnackbarProvider";

export function DevicesRoute(): React.ReactElement {
  const loadKey = React.useRef(1);

  const [list, setList] = React.useState<Device[] | undefined>();

  const load = async () => {
    setList(await DeviceApi.ValidatedList());
  };

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

  return (
    <SolarEnergyRouteContainer
      label="Devices"
      actions={
        <Tooltip title="Refresh table">
          <IconButton onClick={reload}>
            <RefreshIcon />
          </IconButton>
        </Tooltip>
      }
    >
      <AsyncWidget
        loadKey={loadKey.current}
        ready={!!list}
        errMsg="Failed to load the list of validated devices!"
        load={load}
        build={() => <ValidatedDevicesList onReload={reload} list={list!} />}
      />
    </SolarEnergyRouteContainer>
  );
}

function ValidatedDevicesList(p: {
  list: Device[];
  onReload: () => void;
}): React.ReactElement {
  const alert = useAlert();
  const confirm = useConfirm();
  const snackbar = useSnackbar();
  const loadingMessage = useLoadingMessage();

  const deleteDevice = async (d: Device) => {
    try {
      if (
        !(await confirm(
          `Do you really want to delete the device ${d.id}? The operation cannot be reverted!`
        ))
      )
        return;

      loadingMessage.show("Deleting device...");
      await DeviceApi.Delete(d);

      snackbar("The device has been successfully deleted!");
      p.onReload();
    } catch (e) {
      console.error(`Failed to delete device! ${e})`);
      alert("Failed to delete device!");
    } finally {
      loadingMessage.hide();
    }
  };

  if (p.list.length === 0) {
    return <p>There is no device validated yet.</p>;
  }

  return (
    <TableContainer component={Paper}>
      <Table sx={{ minWidth: 650 }} aria-label="simple table">
        <TableHead>
          <TableRow>
            <TableCell>#</TableCell>
            <TableCell>Model</TableCell>
            <TableCell>Version</TableCell>
            <TableCell>Max number of relays</TableCell>
            <TableCell>Created</TableCell>
            <TableCell>Updated</TableCell>
            <TableCell></TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {p.list.map((dev) => (
            <TableRow key={dev.id}>
              <TableCell component="th" scope="row">
                {dev.id}
              </TableCell>
              <TableCell>{dev.info.reference}</TableCell>
              <TableCell>{dev.info.version}</TableCell>
              <TableCell>{dev.info.max_relays}</TableCell>
              <TableCell>
                <TimeWidget time={dev.time_create} />
              </TableCell>
              <TableCell>
                <TimeWidget time={dev.time_update} />
              </TableCell>
              <TableCell>
                <Tooltip title="Delete device">
                  <IconButton onClick={() => deleteDevice(dev)}>
                    <DeleteIcon />
                  </IconButton>
                </Tooltip>
              </TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </TableContainer>
  );
}
