import { Box, Grid2, Typography } from "@mui/material";
import DisplayDrawer from "common/DisplayDrawer";
import ResponsiveTable from "common/ResponsiveTable";
//import DeviceCardList from "device/DeviceCardList";
import { useGroupAPI, useSnackbar } from "hooks";
import { cloneDeep } from "lodash";
import { Group } from "models";
import moment from "moment";
import { describePower } from "pbHelpers/Power";
import BindaptIcon from "products/Bindapt/BindaptIcon";
import { pond } from "protobuf-ts/pond";
import React, { useEffect, useState, useCallback } from "react";
import { useNavigate } from "react-router-dom";
import { or } from "utils";

interface Props {
  open: boolean;
  groups: Map<string, Group>;
  selectedGroup: string;
  onClose: () => void;
  removeMarker: (key: string) => void;
  moveMap: (long: number, lat: number) => void;
}

export default function GroupDrawer(props: Props) {
  const { open, groups, selectedGroup, onClose, moveMap, removeMarker } = props;
  const [group, setGroup] = useState<Group>(Group.create());
  const groupAPI = useGroupAPI();
  const { openSnack } = useSnackbar();
  const [grpDevs, setGrpDevs] = useState<pond.ComprehensiveDevice[]>([]);
  const navigate = useNavigate();
  const loadLimit = 10
  const [groupTotal, setGroupTotal] = useState(0)

  const loadDevs = useCallback(() => {
    groupAPI
      .listGroupDevices(group.id(), loadLimit, 0, "asc", undefined, true)
      .then(resp => {
        const groupDevices: pond.ComprehensiveDevice[] = or(
          resp.data.comprehensiveDevices,
          []
        ).map(d => pond.ComprehensiveDevice.fromObject(d));
        setGrpDevs(groupDevices);
        setGroupTotal(resp.data.total)
      })
      .catch(err => {
        openSnack("Failed to get devices for group");
      });
  }, [group, groupAPI, openSnack]);

  useEffect(() => {
    loadDevs();
  }, [loadDevs]);

  useEffect(() => {
    let g = groups.get(selectedGroup);
    if (g) {
      setGroup(g);
    }
  }, [selectedGroup, groups]);

  const closeDrawer = () => {
    onClose();
  };

  const displayNext = () => {
    let groupArr = Array.from(groups.values());
    let index = groupArr.indexOf(group);
    let found = false;
    do {
      if (index === groupArr.length - 1) {
        index = 0;
      } else {
        index++;
      }
      let next = groupArr[index];
      if (
        next.settings.longitude !== 0 &&
        next.settings.longitude !== 0 &&
        next.settings.latitude !== undefined &&
        next.settings.longitude !== undefined
      ) {
        setGroup(next);
        moveMap(next.settings.longitude, next.settings.latitude);
        found = true;
      }
    } while (!found);
  };

  const displayPrev = () => {
    let groupArr = Array.from(groups.values());
    let index = groupArr.indexOf(group);
    let found = false;
    do {
      if (index === 0) {
        index = groupArr.length - 1;
      } else {
        index--;
      }
      let next = groupArr[index];
      if (
        next.settings.longitude !== 0 &&
        next.settings.longitude !== 0 &&
        next.settings.latitude !== undefined &&
        next.settings.longitude !== undefined
      ) {
        setGroup(next);
        moveMap(next.settings.longitude, next.settings.latitude);
        found = true;
      }
    } while (!found);
  };

  /**
   * function to remove the marker and coordinates from the object
   */
  const remove = () => {
    //set the long/lat of the yard to 0 and call an update
    let settings = group.settings;
    settings.longitude = 0;
    settings.latitude = 0;
    groupAPI
      .updateGroup(group.id(), settings)
      .then(resp => {
        openSnack("Marker Removed");
        //then use the removeMarker prop function to update the markers in the parent map
        removeMarker(group.id().toString());
      })
      .catch(err => {
        openSnack("Failed to remove marker");
      });
  };

  const toDevice = (comprehensiveDevice: pond.ComprehensiveDevice) => {
    let device = comprehensiveDevice.device
    if(device){
      let url = "/groups/" + selectedGroup
      url = url + "/devices/" + device.settings?.deviceId
      navigate(url, { replace: true, state: {device: device} })
    }
  };

  const mobile = (row: pond.ComprehensiveDevice) => {
    return (
      <Box sx={{ margin: 2 }}>
        <Grid2 spacing={1} container direction={"row"} justifyContent="space-between" alignItems={"center"}>
          <Grid2 >
            {/* {GetDeviceProductIcon(row)} */}
            {/* {icon} */}
            <BindaptIcon />
          </Grid2>
          <Grid2 size={{ xs: 9}}>
            <Grid2 container direction="column">
              <Grid2>
                {row.device?.settings?.name}
              </Grid2>
              <Grid2>
                Last Active: {moment(row.device?.status?.lastActive).fromNow()}
              </Grid2>
            </Grid2>
          </Grid2>
          <Grid2 >
            {describePower(row.device?.status?.power).icon}
          </Grid2>
        </Grid2>
      </Box>
    )
  }

  const gutter = (row: pond.ComprehensiveDevice) => {
    return (
      <Box padding={1}>
        <Typography>{row.device?.settings?.description}</Typography>
      </Box>
    )
  }

  const drawerBody = () => {
    return (
      <Box>
        <ResponsiveTable<pond.ComprehensiveDevice>
          page={0}
          pageSize={loadLimit}
          onRowClick={toDevice}
          total={groupTotal}
          rows={grpDevs}
          renderMobile={mobile}
          renderGutter={gutter}
          gutterPadding={0}
          mobileView
          loadMore={() => {
            let current = cloneDeep(grpDevs)
            groupAPI
            .listGroupDevices(group.id(), loadLimit, current.length, "asc", undefined, true)
            .then(resp => {
              let newDevices: pond.ComprehensiveDevice[] = or(
                resp.data.comprehensiveDevices,
                []
              ).map(d => pond.ComprehensiveDevice.fromObject(d));
              setGrpDevs(current.concat(newDevices));
              setGroupTotal(resp.data.total)
            })
            .catch(err => {
              openSnack("Failed to get devices for group");
            });
          }}
          //these two function are uneccessary as this will always be in a list as mobile view
          handleRowsPerPageChange={()=>{}}
          setPage={()=>{}}
        />
      </Box>
    )
    //return <DeviceCardList devices={grpDevs} refreshCallback={loadDevs} showMobile={true} />;
  };

  return (
    <React.Fragment>
      <DisplayDrawer
        open={open}
        onClose={closeDrawer}
        displayNext={displayNext}
        displayPrev={displayPrev}
        title={group.name()}
        width={"40vw"}
        drawerBody={drawerBody()}
        //updateElement={update}
        removeElement={remove}
      />
    </React.Fragment>
  );
}