import {
  Divider,
  IconButton,
  ListItemIcon,
  ListItemText,
  Menu,
  MenuItem,
  Theme,
  Tooltip
} from "@mui/material";
// import { amber, blue, green } from "@mui/co";
import {
  AddCircle as AddIcon,
  ExitToApp as RemoveSelfIcon,
  History as HistoryIcon,
  MoreVert as MoreIcon,
  PauseCircleFilled,
  PlayCircleFilled,
  Reorder as ComponentOrderIcon,
  Save as SaveDeviceProfileIcon,
  SaveAlt as LoadDeviceProfileIcon,
  Settings as DeviceSettingsIcon,
  Share as ShareObjectIcon,
  AccountCircle as ObjectUsersIcon,
  SupervisedUserCircle as ObjectTeamsIcon,
  Sync as SyncDeviceIcon,
  Wifi as WifiIcon,
  Visibility
} from "@mui/icons-material";
import { Skeleton } from "@mui/material";
// import Datadog from "assets/external/datadog.png";
// import { ImgIcon } from "common/ImgIcon";
import NotificationButton from "common/NotificationButton";
// import ComponentOrder from "component/ComponentOrder";
// import ComponentSettings from "component/ComponentSettings";
// import DeviceSettings from "device/DeviceSettings";
// import LoadDeviceProfile from "device/LoadDeviceProfile";
import { PauseData } from "device/PauseData";
import { ResumeData } from "device/ResumeData";
// import SaveDeviceProfile from "device/SaveDeviceProfile";
import SyncDevice from "device/SyncDevice";
// import UpgradeDevice from "device/UpgradeDevice";
// import InteractionSettings from "interactions/InteractionSettings";
import { cloneDeep } from "lodash";
// import { Component, Device, deviceScope, Interaction } from "models";
import { Component, Device, deviceScope, Interaction } from "models";
// import { MatchParams } from "navigation/Routes";
// import { isShareableLink } from "pbHelpers/Device";
import { pond } from "protobuf-ts/pond";
import { useGlobalState } from "providers";
import React, { useEffect, useState } from "react";
// import { useHistory, useRouteMatch } from "react-router";
import { isOffline } from "utils/environment";
import { or } from "utils/types";
import ObjectUsers from "user/ObjectUsers";
import RemoveSelfFromObject from "user/RemoveSelfFromObject";
import ShareObject from "user/ShareObject";
// import Connection from "./Connection";
// import ObjectTeams from "teams/ObjectTeams";
// import ArcGISDeviceData from "./ArcGISDeviceData";
import { DeviceAvailabilityMap, OffsetAvailabilityMap } from "pbHelpers/DeviceAvailability";
import { amber, blue, green } from "@mui/material/colors";
import { makeStyles } from "@mui/styles";
import { useNavigate } from "react-router-dom";
import DeviceSettings from "device/DeviceSettings";
import ObjectTeams from "teams/ObjectTeams";
import ComponentSettings from "component/ComponentSettings";
import LoadDeviceProfile from "./LoadDeviceProfile";
import InteractionSettings from "interactions/InteractionSettings";
import SaveDeviceProfile from "./SaveDeviceProfile";
import Connection from "./Connection";
import ComponentOrder from "component/ComponentOrder";
import ArcGISDeviceData from "./ArcGISDeviceData";
import UpgradeDevice from "./UpgradeDevice";
import { DevicePageData } from "pages/Device";
import { quack } from "protobuf-ts/quack";

const useStyles = makeStyles((_theme: Theme) => {
  // const isMobile = useMobile()
  return ({
    greenIcon: {
      color: green["500"],
      "&:hover": {
        color: green["600"]
      }
    },
    amberIcon: {
      color: amber["600"],
      "&:hover": {
        color: amber["700"]
      }
    },
    blueIcon: {
      color: blue["500"],
      "&:hover": {
        color: blue["600"]
      }
    },
    red: {
      color: "var(--status-alert)"
    }
  });
});

interface Props {
  device: Device;
  isPaused: boolean;
  components: Component[];
  interactions: Interaction[];
  refreshCallback: () => void;
  availablePositions: DeviceAvailabilityMap;
  availableOffsets: OffsetAvailabilityMap;
  permissions: Array<pond.Permission>;
  preferences: pond.DevicePreferences;
  isLoading: boolean;
  toggleNotificationPreference: Function;
}

interface DialogState {
  isAddComponentDialogOpen: boolean;
  isDeviceSettingsDialogOpen: boolean;
  isShareObjectDialogOpen: boolean;
  isSyncDeviceDialogOpen: boolean;
  isPauseDialogOpen: boolean;
  isResumeDialogOpen: boolean;
  isInteractionSettingsOpen: boolean;
  isObjectUsersDialogOpen: boolean;
  isObjectTeamsDialogOpen: boolean;
  isRemoveSelfDialogOpen: boolean;
  isSaveDeviceProfileOpen: boolean;
  isLoadDeviceProfileOpen: boolean;
  isConnectionDialogOpen: boolean;
  isComponentOrderDialogOpen: boolean;
  isJsonDataDialogOpen: boolean;
}

export default function DeviceActions(props: Props) {
  const {
    device,
    isPaused,
    components,
    interactions,
    refreshCallback,
    availablePositions,
    availableOffsets,
    permissions,
    preferences,
    isLoading,
    toggleNotificationPreference
  } = props;
  const classes = useStyles();
  const [{ user }] = useGlobalState();
  const canWrite = permissions.includes(pond.Permission.PERMISSION_WRITE);
  const navigate = useNavigate();
  // const match = useRouteMatch<MatchParams>();
  const [menuAnchorEl, setMenuAnchorEl] = useState<Element | null>(null);
  const [dialogState, setDialogState] = useState<DialogState>({
    isAddComponentDialogOpen: false,
    isDeviceSettingsDialogOpen: false,
    isShareObjectDialogOpen: false,
    isSyncDeviceDialogOpen: false,
    isPauseDialogOpen: false,
    isResumeDialogOpen: false,
    isInteractionSettingsOpen: false,
    isObjectUsersDialogOpen: false,
    isObjectTeamsDialogOpen: false,
    isRemoveSelfDialogOpen: false,
    isSaveDeviceProfileOpen: false,
    isLoadDeviceProfileOpen: false,
    isConnectionDialogOpen: false,
    isComponentOrderDialogOpen: false,
    isJsonDataDialogOpen: false
  });

  const [devicePageData, setDevicePageData] = useState<DevicePageData | undefined>(undefined);

  useEffect(() => {
    let newPageData: DevicePageData = {
      device: device,
      components: components,
      interactions: interactions,
      preferences: preferences,
      permissions: permissions,
    }
    setDevicePageData(newPageData)
  }, [device, components, interactions, preferences, permissions])

  const openDialog = (target: keyof DialogState) => {
    let updatedDialogState = cloneDeep(dialogState);
    updatedDialogState[target] = true;
    setDialogState(updatedDialogState);
    setMenuAnchorEl(null);
  };

  const closeDialog = (target: keyof DialogState) => {
    let updatedDialogState = cloneDeep(dialogState);
    updatedDialogState[target] = false;
    setDialogState(updatedDialogState);
  };

  const closeAndRefresh = (target: keyof DialogState) => (refresh: boolean) => {
    closeDialog(target);
    if (refresh) props.refreshCallback();
  };

  const deviceMenu = () => {
    const canShare = permissions.includes(pond.Permission.PERMISSION_SHARE);
    const canManageUsers = permissions.includes(pond.Permission.PERMISSION_USERS);
    const canProvision = user.allowedTo("provision");
    const isCellular = device.settings.platform === pond.DevicePlatform.DEVICE_PLATFORM_ELECTRON;
    const canPause = canWrite && isCellular && user.allowedTo("pause-data");
    const isWifi = device.settings.platform === pond.DevicePlatform.DEVICE_PLATFORM_PHOTON;
    // const isShareLink = isShareableLink(match.params.deviceID);
    const isShareLink = false
    const isV2 = device.settings.platform >= pond.DevicePlatform.DEVICE_PLATFORM_V2_CELLULAR

    return (
      <Menu
        id="deviceMenu"
        anchorEl={menuAnchorEl ? menuAnchorEl : null}
        open={menuAnchorEl !== null}
        onClose={() => setMenuAnchorEl(null)}
        disableAutoFocusItem>
        {canWrite && (
          <MenuItem
            onClick={() => {
              openDialog("isAddComponentDialogOpen");
            }}
            dense>
            <ListItemIcon>
              <AddIcon className={classes.greenIcon} />
            </ListItemIcon>
            <ListItemText secondary="Add Component" />
          </MenuItem>
        )}
        {canWrite && (
          <MenuItem onClick={() => openDialog("isInteractionSettingsOpen")} dense>
            <ListItemIcon>
              <AddIcon className={classes.greenIcon} />
            </ListItemIcon>
            <ListItemText secondary="Add Interaction" />
          </MenuItem>
        )}
        {canWrite && <Divider />}

        {!isOffline() && canShare && (
          <MenuItem onClick={() => openDialog("isShareObjectDialogOpen")} dense>
            <ListItemIcon>
              <ShareObjectIcon className={classes.blueIcon} />
            </ListItemIcon>
            <ListItemText secondary="Share" />
          </MenuItem>
        )}
        {canWrite &&
        user.hasAdmin() && (
            <MenuItem onClick={() => openDialog("isSyncDeviceDialogOpen")} dense>
              <ListItemIcon>
                <SyncDeviceIcon className={classes.amberIcon} />
              </ListItemIcon>
              <ListItemText secondary="Resync" />
            </MenuItem>
          )}
        {user.hasFeature("json") && (
          <MenuItem onClick={() => openDialog("isJsonDataDialogOpen")} dense>
            <ListItemIcon>
              <LoadDeviceProfileIcon className={classes.greenIcon} />
            </ListItemIcon>
            <ListItemText secondary="Export Json Data" />
          </MenuItem>
        )}
        <MenuItem onClick={() => openDialog("isComponentOrderDialogOpen")} dense>
          <ListItemIcon>
            <ComponentOrderIcon />
          </ListItemIcon>
          <ListItemText secondary="Component Order" />
        </MenuItem>
        <Divider />

        {canPause && !isPaused && (
          <MenuItem onClick={() => openDialog("isPauseDialogOpen")} dense>
            <ListItemIcon>
              <PauseCircleFilled />
            </ListItemIcon>
            <ListItemText secondary="Pause Data" />
          </MenuItem>
        )}
        {canPause && isPaused && (
          <MenuItem onClick={() => openDialog("isResumeDialogOpen")} dense>
            <ListItemIcon>
              <PlayCircleFilled className={classes.greenIcon} />
            </ListItemIcon>
            <ListItemText secondary="Resume Data" />
          </MenuItem>
        )}
        {(isWifi || isV2) && canWrite && (
          <MenuItem onClick={() => openDialog("isConnectionDialogOpen")} dense>
            <ListItemIcon>
              <WifiIcon />
            </ListItemIcon>
            <ListItemText secondary="Connection" />
          </MenuItem>
        )}
        {(canPause || (isWifi && canWrite)) && <Divider />}
        {canProvision && (
          <MenuItem onClick={() => openDialog("isSaveDeviceProfileOpen")} dense>
            <ListItemIcon>
              <SaveDeviceProfileIcon className={classes.blueIcon} />
            </ListItemIcon>
            <ListItemText secondary="Save Profile" />
          </MenuItem>
        )}
        {canProvision && (
          <MenuItem onClick={() => openDialog("isLoadDeviceProfileOpen")} dense>
            <ListItemIcon>
              <LoadDeviceProfileIcon className={classes.greenIcon} />
            </ListItemIcon>
            <ListItemText secondary="Load Profile" />
          </MenuItem>
        )}
        {canProvision && <Divider />}
        {!isOffline() && canManageUsers && (
          <MenuItem onClick={() => openDialog("isObjectUsersDialogOpen")} dense>
            <ListItemIcon>
              <ObjectUsersIcon />
            </ListItemIcon>
            <ListItemText secondary="Users" />
          </MenuItem>
        )}
        {!isOffline() && canManageUsers && (
          <MenuItem onClick={() => openDialog("isObjectTeamsDialogOpen")} dense>
            <ListItemIcon>
              <ObjectTeamsIcon />
            </ListItemIcon>
            <ListItemText secondary="Teams" />
          </MenuItem>
        )}
        <MenuItem
          onClick={() => {
            // const groupID: number = parseInt(match.params.groupID, 10);
            // const groupPath: string = groupID > 0 ? "/groups/" + groupID.toString() : "";
            const devicePath: string = "/devices/" + device.id().toString();
            // let path = groupPath + devicePath + "/history";
            let path = devicePath + "/history";
            navigate(path);
          }}
          dense>
          <ListItemIcon>
            <HistoryIcon />
          </ListItemIcon>
          <ListItemText secondary="History" />
        </MenuItem>
        {/* {canProvision && (
          <MenuItem
            onClick={() => {
              window.open(
                "https://app.datadoghq.com/logs?cols=core_host%2Ccore_service&index=main&live=true&messageDisplay=inline&stream_sort=desc&query=%40device%3A" +
                  device.id(),
                "_blank"
              );
            }}
            dense>
            <ListItemIcon>
              <ImgIcon src={Datadog} />
            </ListItemIcon>
            <ListItemText secondary="Datadog" />
          </MenuItem>
        )} */}
        <Divider />
        {!isShareLink && (
          <MenuItem onClick={() => openDialog("isRemoveSelfDialogOpen")} dense>
            <ListItemIcon>
              <RemoveSelfIcon className={classes.red} />
            </ListItemIcon>
            <ListItemText secondary="Leave" />
          </MenuItem>
        )}
      </Menu>
    );
  };

  const dialogs = () => {
    const deviceName = device.name();
    const {
      isAddComponentDialogOpen,
      isDeviceSettingsDialogOpen,
      isShareObjectDialogOpen,
      isSyncDeviceDialogOpen,
      isPauseDialogOpen,
      isResumeDialogOpen,
      isInteractionSettingsOpen,
      isObjectUsersDialogOpen,
      isObjectTeamsDialogOpen,
      isRemoveSelfDialogOpen,
      isSaveDeviceProfileOpen,
      isLoadDeviceProfileOpen,
      isConnectionDialogOpen,
      isComponentOrderDialogOpen,
      isJsonDataDialogOpen
    } = dialogState;

    return (
      <React.Fragment>
        <DeviceSettings
          device={device}
          isDialogOpen={or(isDeviceSettingsDialogOpen, false)}
          closeDialogCallback={() => closeDialog("isDeviceSettingsDialogOpen")}
          refreshCallback={refreshCallback}
          canEdit={canWrite}
          components={components}
          //components={[]}
        />
        <ComponentSettings
          mode="add"
          device={device}
          isDialogOpen={or(isAddComponentDialogOpen, false)}
          closeDialogCallback={() => closeDialog("isAddComponentDialogOpen")}
          availablePositions={availablePositions}
          availableOffsets={availableOffsets}
          refreshCallback={refreshCallback}
          canEdit={canWrite}
        />
        <SyncDevice
          device={device}
          isDialogOpen={or(isSyncDeviceDialogOpen, false)}
          closeDialogCallback={() => closeDialog("isSyncDeviceDialogOpen")}
          refreshCallback={refreshCallback}
        />
        <ShareObject
          scope={deviceScope(device.id().toString())}
          label={deviceName}
          permissions={permissions}
          isDialogOpen={or(isShareObjectDialogOpen, false)}
          closeDialogCallback={() => closeDialog("isShareObjectDialogOpen")}
        />
        <InteractionSettings
          device={device}
          components={cloneDeep(components)}
          mode="add"
          isDialogOpen={or(isInteractionSettingsOpen, false)}
          closeDialogCallback={() => closeDialog("isInteractionSettingsOpen")}
          refreshCallback={refreshCallback}
          canEdit={canWrite}
        />
        <ObjectUsers
          scope={deviceScope(device.id().toString())}
          label={deviceName}
          permissions={permissions}
          isDialogOpen={or(isObjectUsersDialogOpen, false)}
          closeDialogCallback={() => closeDialog("isObjectUsersDialogOpen")}
          refreshCallback={refreshCallback}
        />
        <ObjectTeams
          scope={deviceScope(device.id().toString())}
          label={deviceName}
          permissions={permissions}
          isDialogOpen={or(isObjectTeamsDialogOpen, false)}
          closeDialogCallback={() => closeDialog("isObjectTeamsDialogOpen")}
          refreshCallback={refreshCallback}
        />
        <RemoveSelfFromObject
          scope={deviceScope(device.id().toString())}
          label={deviceName}
          isDialogOpen={isRemoveSelfDialogOpen}
          closeDialogCallback={() => closeDialog("isRemoveSelfDialogOpen")}
        />
        <SaveDeviceProfile
          isDialogOpen={isSaveDeviceProfileOpen}
          closeDialogCallback={() => closeDialog("isSaveDeviceProfileOpen")}
          device={device}
          components={components}
          interactions={interactions}
          tagIds={device.status.tagKeys}
          refreshCallback={refreshCallback}
        />
        <LoadDeviceProfile
          isDialogOpen={isLoadDeviceProfileOpen}
          closeDialogCallback={() => closeDialog("isLoadDeviceProfileOpen")}
          device={device}
          refreshCallback={refreshCallback}
        />
        <PauseData
          id={device.id()}
          isOpen={isPauseDialogOpen}
          close={closeAndRefresh("isPauseDialogOpen")}
        />
        <ResumeData
          id={device.id()}
          isOpen={isResumeDialogOpen}
          close={closeAndRefresh("isResumeDialogOpen")}
        />
        <Connection
          deviceID={device.id()}
          open={isConnectionDialogOpen}
          close={closeAndRefresh("isConnectionDialogOpen")}
          deviceName={device.name()}
        />
        <ComponentOrder
          device={device}
          devicePreferences={preferences}
          components={components}
          open={isComponentOrderDialogOpen}
          close={closeAndRefresh("isComponentOrderDialogOpen")}
        />
        <ArcGISDeviceData
          open={isJsonDataDialogOpen}
          close={closeAndRefresh("isJsonDataDialogOpen")}
          device={device}
          components={components}
        />
      </React.Fragment>
    );
  };

  const showSupport = () => {
    return user.allowedTo("provision") && !location.pathname.includes("support")
  }

  const buttons = () => {
    return (
      <React.Fragment>
        {showSupport() && <Tooltip title="Support">
          <IconButton onClick={() => navigate("support", { state: {device: device, devicePageData: devicePageData }})}>
            <Visibility />
          </IconButton>
        </Tooltip>}
        {canWrite && user.allowedTo("provision") && <UpgradeDevice device={device} />}
        {/* {!isShareableLink(match.params.deviceID) && ( */}
          <NotificationButton
            notify={preferences.notify}
            onChange={toggleNotificationPreference}
            tooltip={
              "Notifications for " +
              device.name() +
              " are " +
              (preferences.notify ? "enabled" : "disabled")
            }
            hidden={isLoading}
          />
        {/* )} */}
        <Tooltip title="Settings">
          <IconButton onClick={() => openDialog("isDeviceSettingsDialogOpen")}>
            <DeviceSettingsIcon />
          </IconButton>
        </Tooltip>
        <Tooltip title="More">
          <IconButton
            aria-owns={"deviceMenu"}
            aria-haspopup="true"
            onClick={event => setMenuAnchorEl(event.currentTarget)}>
            <MoreIcon />
          </IconButton>
        </Tooltip>
      </React.Fragment>
    );
  };

  if (isLoading)
    return (
      <Skeleton>
        <IconButton />
        <IconButton />
        <IconButton />
      </Skeleton>
    );

  return (
    <React.Fragment>
      {buttons()}

      {deviceMenu()}
      {dialogs()}
    </React.Fragment>
  );
}
