import { Box } from "@mui/material";
import DisplayDrawer from "common/DisplayDrawer";
import MapMarkerSettings from "maps/MapMarkerSettings";
import { Bin as IBin } from "models";
//import Bin from "pages/Bin";
import { pond } from "protobuf-ts/pond";
import { useBinAPI, useGlobalState, useSnackbar } from "providers";
import React, { lazy, useEffect, useState } from "react";

const Bin = lazy(() => import("pages/Bin"));

interface Props {
  open: boolean;
  onClose: () => void;
  selectedBin: string;
  bins: Map<string, IBin>;
  removeMarker: (key: string) => void;
  updateMarker: (key: string, newSettings: pond.BinSettings) => void;
  moveMap: (long: number, lat: number) => void;
}

export default function BinDrawer(props: Props) {
  const { open, onClose, selectedBin, bins, removeMarker, updateMarker, moveMap } = props;
  const [{as}] = useGlobalState()
  const [bin, setBin] = useState<IBin>(IBin.create());
  const [openMarkerSettings, setOpenMarkerSettings] = useState(false);
  const binAPI = useBinAPI();
  const { openSnack } = useSnackbar();

  useEffect(() => {
    let b = bins.get(selectedBin);
    if (b) {
      setBin(b);
    }
  }, [selectedBin, bins]);

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

  const displayNext = () => {
    let binArr = Array.from(bins.values());
    let index = binArr.indexOf(bin);
    let found = false;
    do {
      if (index === binArr.length - 1) {
        index = 0;
      } else {
        index++;
      }
      let nextBin = binArr[index];
      let location = nextBin.location();
      if (
        location !== null &&
        location !== undefined &&
        location.longitude !== 0 &&
        location.longitude !== 0
      ) {
        setBin(nextBin);
        moveMap(location.longitude, location.latitude);
        found = true;
      }
    } while (!found);
  };

  const displayPrev = () => {
    let binArr = Array.from(bins.values());
    let index = binArr.indexOf(bin);
    let found = false;
    do {
      if (index === 0) {
        index = binArr.length - 1;
      } else {
        index--;
      }
      let nextBin = binArr[index];
      let location = nextBin.location();
      if (
        location !== null &&
        location !== undefined &&
        location.longitude !== 0 &&
        location.longitude !== 0
      ) {
        setBin(nextBin);
        moveMap(location.longitude, location.latitude);
        found = true;
      }
    } while (!found);
  };

  const drawerBody = () => {
    return <Box>{bin.key() !== "" && <Bin binKey={bin.key()} displayMobile fromMap />}</Box>;
  };

  const remove = () => {
    let settings = bin.settings;
    settings.location = null;

    binAPI
      .updateBin(bin.key(), settings, as)
      .then(resp => {
        openSnack("Removed bin marker");
        removeMarker(bin.key());
      })
      .catch(err => {
        openSnack("Failed to remove bin marker");
      });
  };

  const update = () => {
    setOpenMarkerSettings(true);
  };

  return (
    <React.Fragment>
      <DisplayDrawer
        open={open}
        onClose={closeDrawer}
        displayNext={displayNext}
        displayPrev={displayPrev}
        title={bin.name()}
        width={"40vw"}
        drawerBody={drawerBody()}
        updateElement={update}
        removeElement={remove}
      />
      <MapMarkerSettings
        close={() => {
          setOpenMarkerSettings(false);
        }}
        open={openMarkerSettings}
        theme={bin.settings.theme ?? pond.ObjectTheme.create()}
        sizeControl
        currentSize={bin.settings.theme?.height}
        updateObject={newTheme => {
          let settings = bin.settings;
          settings.theme = newTheme;
          binAPI
            .updateBin(bin.key(), settings, as)
            .then(resp => {
              openSnack("marker settings updated");
              updateMarker(bin.key(), settings);
            })
            .catch(() => {
              openSnack("failed to update marker settings");
            });
        }}
      />
    </React.Fragment>
  );
}