import api from 'api/api';
import { useSnackbar } from 'notistack';
import React, { useEffect, useMemo, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useHistory, useLocation } from 'react-router-dom';
import styled from 'styled-components';

import {
  Avatar,
  Button,
  CircularProgress,
  IconButton,
  Tooltip,
} from '@material-ui/core';
import { PersonOutline } from '@material-ui/icons';

import UserProfile from './UserProfile';
import {
  makeSignedInChange,
  selectIsSignedIn,
  selectLoading,
  selectProfile,
  selectUserRoles,
} from './userSlice';

const StyledAvatar = styled(Avatar)`
  width: ${({ theme }) => theme.spacing(3)}px;
  height: ${({ theme }) => theme.spacing(3)}px;
`;
const StyledProgress = styled(CircularProgress)`
  position: absolute;
  top: ${({ theme }) => theme.spacing(1.1)}px;
  left: ${({ theme }) => theme.spacing(1.1)}px;
  z-index: 1;
`;
const Wrapper = styled.div`
  position: relative;
`;
const UserButton = () => {
  const isSignedIn = useSelector(selectIsSignedIn);
  const loading = useSelector(selectLoading);
  const profile = useSelector(selectProfile);
  const roles = useSelector(selectUserRoles);
  const [openDialog, setOpenDialog] = useState(false);
  const dispatch = useDispatch();
  const { enqueueSnackbar, closeSnackbar } = useSnackbar();
  const handleSignedInChange = useMemo(
    () => makeSignedInChange(enqueueSnackbar),
    [enqueueSnackbar],
  );
  const { state, pathname } = useLocation<{ referrer: string } | undefined>();
  const { replace } = useHistory();

  const handleCloseDialog = (signOut?: boolean) => {
    setOpenDialog(false);
    if (signOut) {
      api.signOut();
      enqueueSnackbar('You have been logged out', {
        key: 'user-logged-out',
        action: () => (
          <Button
            color="primary"
            onClick={() => {
              api.signIn();
              closeSnackbar();
            }}
          >
            Log In
          </Button>
        ),
      });
    }
  };
  useEffect(() => {
    if (isSignedIn && state?.referrer && pathname !== state?.referrer)
      replace(state.referrer);
  }, [state, pathname, isSignedIn, replace]);
  useEffect(() => {
    api.active.then(() => {
      api.attachListener(signedIn => dispatch(handleSignedInChange(signedIn)));
    });
  }, [dispatch, handleSignedInChange]);

  return (
    <>
      <Tooltip title={isSignedIn ? 'View Profile' : 'Log In'}>
        <Wrapper>
          <IconButton
            aria-label="view profile"
            edge="end"
            disabled={loading}
            onClick={() => (isSignedIn ? setOpenDialog(true) : api.signIn())}
          >
            {isSignedIn && profile ? (
              <StyledAvatar
                src={profile.image.replace(/-o=.*$/, '-o=s50')}
                alt="Profile Picture"
              />
            ) : (
              <PersonOutline />
            )}
          </IconButton>
          {loading && <StyledProgress color="secondary" size={30} />}
        </Wrapper>
      </Tooltip>
      {isSignedIn && profile && roles ? (
        <UserProfile
          open={isSignedIn && openDialog}
          handleClose={handleCloseDialog}
          image={profile.image}
          name={profile.name}
          email={profile.email}
          roles={roles}
        />
      ) : null}
    </>
  );
};

export default UserButton;
