import {
  Box,
  Card,
  Checkbox,
  CircularProgress,
  Divider,
  Grid,
  IconButton,
  MenuItem,
  Select,
  Tab,
  Tabs,
  Theme,
  Typography
} from "@mui/material";
import DeviceIcon from "assets/editor/device.png";
import React, { useEffect, useState } from "react";
import { pond } from "protobuf-ts/pond";
import { useDeviceAPI, useMineAPI } from "hooks";
import LeftIcon from "@mui/icons-material/KeyboardArrowLeft";
import RightIcon from "@mui/icons-material/KeyboardArrowRight";
import { makeStyles } from "@mui/styles";
import { useGlobalState } from "providers";

const useStyles = makeStyles((theme: Theme) => {
  return ({
    topText: {
      //textAlign: "center",
      //alignContent: "center"
    },
    bottom: {
      display: "flex",
      alignItems: "center",
      width: "100%",
      paddingRight: theme.spacing(1),
      paddingLeft: theme.spacing(1),
      marginTop: theme.spacing(1)
    },
    bottomButtons: {
      marginLeft: "auto",
      justifyContent: "center",
      alignContent: "center"
    },
    divider: {
      margin: theme.spacing(2)
    },
    topTextContainer: {
      width: "100%",
      marginLeft: "auto",
      marginRight: "auto",
      padding: theme.spacing(1),
      marginBottom: 0,
      paddingBottom: 0
    },
    deviceCard: {
      display: "flex",
      flexDirection: "row",
      padding: theme.spacing(1),
      marginTop: theme.spacing(1),
      height: theme.spacing(8)
    },
    skeletonCard: {
      marginTop: theme.spacing(1),
      height: theme.spacing(8),
      borderRadius: "6px"
    },
    fanIcon: {
      height: "100%",
      objectFit: "contain"
    },
    iconContainer: {
      height: "100%",
      width: theme.spacing(8)
    },
    deviceInfo: {
      display: "block",
      margin: "auto",
      marginLeft: theme.spacing(1),
      padding: 0
    },
    checkbox: {
      marginLeft: "auto",
      marginTop: "auto",
      marginBottom: "auto"
    },
    tab: {
      width: "50%",
      maxWidth: "50%"
    }
  });
});

interface Props {
  addBlockRef: any;
  selectedDevices: pond.Device[];
  setSelectedDevices: any;
  mine: pond.MineSettings;
  setMine: React.Dispatch<React.SetStateAction<pond.MineSettings>>;
}

export default function DeviceDrawer(props: Props) {
  //const isMobile = useMobile();
  const { selectedDevices, setSelectedDevices, mine } = props;
  const classes = useStyles();
  //const addBlockRef = props.addBlockRef;
  const [devices, setDevices] = useState<pond.Device[]>([]);
  const [loading, setLoading] = useState<boolean>(true);
  const [total, setTotal] = useState<number>(0);
  const [offset, setOffset] = useState<number>(0);
  const [limit, setLimit] = useState<number>(5);
  const [selectedIDs, setSelectedIDs] = useState<number[]>([]);
  const deviceAPI = useDeviceAPI();
  const mineAPI = useMineAPI();
  const [tab, setTab] = React.useState(0);
  const [{as}] = useGlobalState();

  useEffect(() => {
    let ids: number[] = [];
    selectedDevices.forEach(dev => {
      if (dev.settings) {
        ids.push(dev.settings.deviceId);
      }
    });
    setSelectedIDs([...ids]);
  }, [selectedDevices]);

  useEffect(() => {
    setLoading(true);
    deviceAPI.list(limit, offset, undefined, undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,as).then(resp => {
      setDevices(resp.data.devices);
      setTotal(resp.data.total);
      setLoading(false);
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [limit, offset, deviceAPI, as]);

  const back = () => {
    if (offset - limit < 0) {
      setOffset(0);
    } else {
      setOffset(offset - limit);
    }
  };

  const forward = () => {
    if (offset + limit > total) {
      setOffset(total - limit);
    } else {
      setOffset(offset + limit);
    }
  };

  const toggleDevice = (device: pond.Device) => {
    let id = device.settings ? device.settings.deviceId : 0;
    const index = selectedIDs.indexOf(id);
    if (index > -1) {
      if (device.settings && mine.name !== "") {
        mineAPI.addDevice(mine.key, device.settings.deviceId.toString(), [], as).then(resp => {
          selectedIDs.splice(index, 1);
          let d = selectedDevices;
          let deviceIndex = 0;
          d.forEach((device, i) => {
            let key = device.settings ? device.settings.deviceId : 0;
            if (key === id) {
              deviceIndex = i;
            }
          });
          d.splice(deviceIndex, 1);
          setSelectedDevices([...d]);
        });
      }
    } else {
      if (device.settings && mine) {
        mineAPI
          .addDevice(mine.key, device.settings.deviceId.toString(), [
            pond.Permission.PERMISSION_READ,
            pond.Permission.PERMISSION_SHARE,
            pond.Permission.PERMISSION_WRITE,
            pond.Permission.PERMISSION_USERS
          ], as)
          .then(resp => {
            selectedIDs.push(id);
            let d = selectedDevices;
            d.push(device);
            setSelectedDevices([...d]);
          });
      }
    }
  };

  const yourDevices = () => {
    if (loading) return <CircularProgress />;

    return devices.map((device: pond.Device, i) => {
      let name = device.settings?.name
        ? device.settings?.name
        : "Device " + device.settings?.deviceId;
      return (
        <Card key={i} className={classes.deviceCard}>
          <div className={classes.iconContainer}>
            <img src={DeviceIcon} alt={device.settings?.name} className={classes.fanIcon} />
          </div>
          <div className={classes.deviceInfo}>
            <Typography display="block" variant="body2">
              {name}
            </Typography>
          </div>
          <Checkbox
            className={classes.checkbox}
            checked={device.settings ? selectedIDs.indexOf(device.settings!.deviceId) > -1 : false}
            onChange={() => device.settings && toggleDevice(device)}
          />
        </Card>
      );
    });
  };

  const attachedDevices = () => {
    if (loading) return <CircularProgress />;

    return selectedDevices.map((device: pond.Device) => {
      let name = device.settings?.name
        ? device.settings?.name
        : "Device " + device.settings?.deviceId;
      return (
        <Card key={device.settings?.name} className={classes.deviceCard}>
          <div className={classes.iconContainer}>
            <img src={DeviceIcon} alt={device.settings?.name} className={classes.fanIcon} />
          </div>
          <div className={classes.deviceInfo}>
            <Typography display="block" variant="body2">
              {name}
            </Typography>
          </div>
          <Checkbox
            className={classes.checkbox}
            checked={device.settings ? selectedIDs.indexOf(device.settings!.deviceId) > -1 : false}
            onChange={() => device.settings && toggleDevice(device)}
          />
        </Card>
      );
    });
  };

  const bottom = () => {
    return (
      <div className={classes.bottom}>
        {offset + 1} - {devices.length + offset} of {total}
        <div className={classes.bottomButtons}>
          <Grid container justifyContent="center">
            <IconButton onClick={back} size="small">
              <LeftIcon />
            </IconButton>
            <Select value={limit} onChange={event => setLimit(event.target.value as number)}>
              <MenuItem value={5}>5</MenuItem>
              <MenuItem value={10}>10</MenuItem>
              <MenuItem value={15}>15</MenuItem>
            </Select>
            <IconButton onClick={forward} size="small">
              <RightIcon />
            </IconButton>
          </Grid>
        </div>
      </div>
    );
  };

  const handleTabChange = (event: React.ChangeEvent<{}>, newValue: number) => {
    setTab(newValue);
  };

  return (
    <React.Fragment>
      <div className={classes.topTextContainer}>
        <Typography className={classes.topText} color="textSecondary" variant="caption">
          Devices you have access to are listed below. Click the check box to gain access to the
          device's sensor in the editor. Devices that you and others have added can be seen in the
          second tab.
        </Typography>
      </div>
      <Divider className={classes.divider} />
      <Box component="span">
        <Tabs
          style={{ width: "100%", maxWidth: "100%" }}
          value={tab}
          onChange={handleTabChange}
          aria-label="basic tabs example">
          <Tab label="Devices" classes={{ root: classes.tab }} />
          <Tab label="Attached" classes={{ root: classes.tab }} />
        </Tabs>
      </Box>
      {tab === 0 ? yourDevices() : attachedDevices()}
      {bottom()}
    </React.Fragment>
  );
}
