import {
  Button,
  DialogActions,
  DialogContent,
  DialogTitle,
  IconButton,
  ListItemIcon,
  ListItemText,
  Menu,
  MenuItem,
  TextField,
  Theme,
  Tooltip
} from "@mui/material";
import { blue } from "@mui/material/colors";
import RemoveSelfIcon from "@mui/icons-material/ExitToApp";
import MoreIcon from "@mui/icons-material/MoreVert";
import ShareObjectIcon from "@mui/icons-material/Share";
import ObjectUsersIcon from "@mui/icons-material/AccountCircle";
import ObjectTeamsIcon from "@mui/icons-material/SupervisedUserCircle";
import { pond } from "protobuf-ts/pond";
import React, { useState } from "react";
import ObjectUsers from "user/ObjectUsers";
import RemoveSelfFromObject from "user/RemoveSelfFromObject";
import ShareObject from "user/ShareObject";
import { isOffline } from "utils/environment";
import ObjectTeams from "teams/ObjectTeams";
import { siteScope, Site } from "models";
import ResponsiveDialog from "common/ResponsiveDialog";
import { useGlobalState, useSiteAPI } from "providers";
import { useSnackbar } from "hooks";
import GroupSettingsIcon from "@mui/icons-material/Settings";
import { makeStyles } from "@mui/styles";

const useStyles = makeStyles((theme: Theme) => ({
    shareIcon: {
      color: blue["500"],
      "&:hover": {
        color: blue["600"]
      }
    },
    removeIcon: {
      color: "var(--status-alert)"
    },
    red: {
      color: "var(--status-alert)"
    }
}));

interface Props {
  site: Site;
  permissions: pond.Permission[];
  refreshCallback: () => void;
}

interface OpenState {
  share: boolean;
  users: boolean;
  teams: boolean;
  settings: boolean;
  removeSelf: boolean;
}

export default function SiteActions(props: Props) {
  const classes = useStyles();
  const [{as}] = useGlobalState();
  const { site, permissions, refreshCallback } = props;
  const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
  const [siteDialog, setSiteDialog] = useState(false);
  const [deleteConfirmation, setDeleteConfirmation] = useState(false);
  const siteAPI = useSiteAPI();
  const [siteName, setSiteName] = useState(site.siteName());
  const [update, setUpdate] = useState(false);
  const { openSnack } = useSnackbar();
  const [openState, setOpenState] = useState<OpenState>({
    share: false,
    users: false,
    teams: false,
    settings: false,
    removeSelf: false
  });

  const groupMenu = () => {
    const canShare = permissions.includes(pond.Permission.PERMISSION_SHARE);
    const canManageUsers = permissions.includes(pond.Permission.PERMISSION_USERS);
    return (
      <Menu
        id="groupMenu"
        anchorEl={anchorEl}
        open={Boolean(anchorEl)}
        onClose={() => setAnchorEl(null)}
        keepMounted
        disableAutoFocusItem>
        {!isOffline() && canShare && (
          <MenuItem
            dense
            onClick={() => {
              setOpenState({ ...openState, share: true });
              setAnchorEl(null);
            }}>
            <ListItemIcon>
              <ShareObjectIcon className={classes.shareIcon} />
            </ListItemIcon>
            <ListItemText primary="Share" />
          </MenuItem>
        )}
        {!isOffline() && canManageUsers && (
          <MenuItem
            dense
            onClick={() => {
              setOpenState({ ...openState, users: true });
              setAnchorEl(null);
            }}>
            <ListItemIcon>
              <ObjectUsersIcon />
            </ListItemIcon>
            <ListItemText primary="Users" />
          </MenuItem>
        )}
        {!isOffline() && canManageUsers && (
          <MenuItem
            dense
            onClick={() => {
              setOpenState({ ...openState, teams: true });
              setAnchorEl(null);
            }}>
            <ListItemIcon>
              <ObjectTeamsIcon />
            </ListItemIcon>
            <ListItemText primary="Teams" />
          </MenuItem>
        )}
        <MenuItem
          dense
          onClick={() => {
            setOpenState({ ...openState, removeSelf: true });
            setAnchorEl(null);
          }}>
          <ListItemIcon>
            <RemoveSelfIcon className={classes.red} />
          </ListItemIcon>
          <ListItemText primary="Leave" />
        </MenuItem>
      </Menu>
    );
  };

  const dialogs = () => {
    const key = site.key();
    const label = site.siteName();
    return (
      <React.Fragment>
        <ShareObject
          scope={siteScope(key)}
          label={label}
          permissions={permissions}
          isDialogOpen={openState.share}
          closeDialogCallback={() => setOpenState({ ...openState, share: false })}
        />
        <ObjectUsers
          scope={siteScope(key)}
          label={label}
          permissions={permissions}
          isDialogOpen={openState.users}
          closeDialogCallback={() => setOpenState({ ...openState, users: false })}
          refreshCallback={refreshCallback}
        />
        <RemoveSelfFromObject
          scope={siteScope(key)}
          label={label}
          isDialogOpen={openState.removeSelf}
          closeDialogCallback={() => setOpenState({ ...openState, removeSelf: false })}
        />
        {dialogForSite()}
        {deleteDialog()}
      </React.Fragment>
    );
  };

  const closeSiteDialog = () => {
    setSiteDialog(false);
    setUpdate(false);
  };

  const updateSite = () => {
    let newSite = site;
    newSite.settings.siteName = siteName;

    siteAPI
      .updateSite(newSite.key(), newSite.settings, undefined, as)
      .then(resp => {
        openSnack("Site Updated");
        closeSiteDialog();
      })
      .catch(err => {
        openSnack("Could Not Update Site");
        closeSiteDialog();
      });
  };

  //deletes a site from the DB and removes the coordinates of that site from the array
  const deleteSite = () => {
    siteAPI
      .removeSite(site.key())
      .then(resp => {
        openSnack("Site has been removed");
        closeSiteDialog();
      })
      .catch(err => {
        openSnack("Site could not be removed");
      });
  };

  const openUpdate = () => {
    setUpdate(true);
    setSiteDialog(true);
  };

  const deleteDialog = () => {
    return (
      <ResponsiveDialog
        fullWidth
        open={deleteConfirmation}
        onClose={() => {
          setDeleteConfirmation(false);
        }}>
        <DialogTitle>Delete Site</DialogTitle>
        <DialogContent>Are you sure you wish to delete {site.siteName()}</DialogContent>
        <DialogActions>
          <Button
            onClick={() => {
              setDeleteConfirmation(false);
            }}
            color="primary">
            Cancel
          </Button>
          <Button onClick={deleteSite} style={{ color: "red" }}>
            Confirm
          </Button>
        </DialogActions>
      </ResponsiveDialog>
    );
  };

  //dialog the renders the forms for creating a new site
  const dialogForSite = () => {
    return (
      <ResponsiveDialog fullWidth fullScreen={false} open={siteDialog} onClose={closeSiteDialog}>
        <DialogTitle>Enter Name of Site</DialogTitle>
        <DialogContent>
          <TextField
            value={siteName}
            color="primary"
            autoFocus
            margin="dense"
            id="name"
            label="Site Name"
            type="text"
            fullWidth
            onChange={e => setSiteName(e.target.value)}
          />
        </DialogContent>
        {update ? (
          <DialogActions>
            <Button
              onClick={() => {
                setDeleteConfirmation(true);
              }}
              style={{ color: "red" }}>
              Delete Site
            </Button>
            <Button onClick={updateSite} color="primary">
              Update Site
            </Button>
          </DialogActions>
        ) : (
          <DialogActions>
            <Button onClick={closeSiteDialog} color="primary">
              Cancel
            </Button>
            {/* <Button onClick={saveSite} color="primary" disabled={siteName === ""}>
              Add Site
            </Button> */}
          </DialogActions>
        )}
      </ResponsiveDialog>
    );
  };

  return (
    <React.Fragment>
      {permissions.includes(pond.Permission.PERMISSION_WRITE) && (
        <Tooltip title="Jobsite Settings">
          <IconButton
            onClick={() => {
              openUpdate();
            }}>
            <GroupSettingsIcon />
          </IconButton>
        </Tooltip>
      )}
      <IconButton
        aria-owns={anchorEl ? "groupMenu" : undefined}
        aria-haspopup="true"
        onClick={(event: React.MouseEvent<HTMLButtonElement>) => setAnchorEl(event.currentTarget)}>
        <MoreIcon />
      </IconButton>
      {groupMenu()}
      {dialogs()}
      <ObjectTeams
        scope={siteScope(site.key())}
        label="Teams"
        permissions={permissions}
        isDialogOpen={openState.teams}
        refreshCallback={refreshCallback}
        closeDialogCallback={() => setOpenState({ ...openState, teams: false })}
      />
    </React.Fragment>
  );
}
