import {
  ChevronLeft as ChevronLeftIcon,
  ChevronRight as ChevronRightIcon,
  CopyAll,
  Delete,
  DriveFileRenameOutline,
  Home as HomeIcon,
  KeyboardArrowDown as KeyboardArrowDownIcon,
  Link as LinkIcon,
} from '@mui/icons-material';
import {
  AppBar,
  IconButton,
  ListItemIcon,
  ListItemText,
  Menu,
  MenuItem,
  Toolbar,
  Tooltip,
  useMediaQuery,
  useTheme,
} from '@mui/material';
import { Resume } from '@reactive-resume/schema';
import clsx from 'clsx';
import get from 'lodash/get';
import { useRouter } from 'next/router';
import { useTranslation } from 'next-i18next';
import { useEffect, useMemo, useState } from 'react';
import toast from 'react-hot-toast';
import { useMutation } from 'react-query';

import { RESUMES_QUERY } from '@/constants/index';
import { ServerError } from '@/services/axios';
import queryClient from '@/services/react-query';
import { deleteResume, DeleteResumeParams, duplicateResume, DuplicateResumeParams } from '@/services/resume';
import { setSidebarState, toggleSidebar } from '@/store/build/buildSlice';
import { useAppDispatch, useAppSelector } from '@/store/hooks';
import { setModalState } from '@/store/modal/modalSlice';
import getResumeUrl from '@/utils/getResumeUrl';

import styles from './Header.module.scss';

const Header = () => {
  const theme = useTheme();

  const router = useRouter();

  const { t } = useTranslation();

  const dispatch = useAppDispatch();

  const isDesktop = useMediaQuery(theme.breakpoints.up('lg'));

  const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);

  const { mutateAsync: duplicateMutation } = useMutation<Resume, ServerError, DuplicateResumeParams>(duplicateResume);

  const { mutateAsync: deleteMutation } = useMutation<void, ServerError, DeleteResumeParams>(deleteResume);

  const resume = useAppSelector((state) => state.resume);
  const { left, right } = useAppSelector((state) => state.build.sidebar);

  const name = useMemo(() => get(resume, 'name'), [resume]);

  useEffect(() => {
    if (isDesktop) {
      dispatch(setSidebarState({ sidebar: 'left', state: { open: true } }));
      dispatch(setSidebarState({ sidebar: 'right', state: { open: true } }));
    } else {
      dispatch(setSidebarState({ sidebar: 'left', state: { open: false } }));
      dispatch(setSidebarState({ sidebar: 'right', state: { open: false } }));
    }
  }, [isDesktop, dispatch]);

  const toggleLeftSidebar = () => dispatch(toggleSidebar({ sidebar: 'left' }));

  const toggleRightSidebar = () => dispatch(toggleSidebar({ sidebar: 'right' }));

  const goBack = () => router.push('/dashboard');

  const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
    setAnchorEl(event.currentTarget);
  };

  const handleClose = () => {
    setAnchorEl(null);
  };

  const handleRename = () => {
    handleClose();

    dispatch(
      setModalState({
        modal: 'dashboard.rename-resume',
        state: {
          open: true,
          payload: {
            item: resume,
            onComplete: (newResume: Resume) => {
              queryClient.invalidateQueries(RESUMES_QUERY);

              router.push(`/${resume.user.username}/${newResume.slug}/build`);
            },
          },
        },
      })
    );
  };

  const handleDuplicate = async () => {
    handleClose();

    const newResume = await duplicateMutation({ id: resume.id });

    queryClient.invalidateQueries(RESUMES_QUERY);

    router.push(`/${resume.user.username}/${newResume.slug}/build`);
  };

  const handleDelete = async () => {
    handleClose();

    await deleteMutation({ id: resume.id });

    queryClient.invalidateQueries(RESUMES_QUERY);

    goBack();
  };

  const handleShareLink = async () => {
    handleClose();

    const url = getResumeUrl(resume, { withHost: true });
    await navigator.clipboard.writeText(url);

    toast.success(t('common.toast.success.resume-link-copied'));
  };

  return (
    <AppBar elevation={0} position="fixed">
      <Toolbar
        variant="regular"
        className={clsx({
          [styles.header]: true,
          [styles.pushLeft]: left.open,
          [styles.pushRight]: right.open,
        })}
      >
        <IconButton onClick={toggleLeftSidebar}>{left.open ? <ChevronLeftIcon /> : <ChevronRightIcon />}</IconButton>

        <div className={styles.title}>
          <IconButton className="opacity-50 hover:opacity-100" onClick={goBack}>
            <HomeIcon />
          </IconButton>

          <span className="opacity-50">{'/'}</span>

          <h1>{name}</h1>

          <IconButton onClick={handleClick}>
            <KeyboardArrowDownIcon />
          </IconButton>

          <Menu open={Boolean(anchorEl)} anchorEl={anchorEl} onClose={handleClose}>
            <MenuItem onClick={handleRename}>
              <ListItemIcon>
                <DriveFileRenameOutline className="scale-90" />
              </ListItemIcon>
              <ListItemText>{t('builder.header.menu.rename')}</ListItemText>
            </MenuItem>

            <MenuItem onClick={handleDuplicate}>
              <ListItemIcon>
                <CopyAll className="scale-90" />
              </ListItemIcon>
              <ListItemText>{t('builder.header.menu.duplicate')}</ListItemText>
            </MenuItem>

            {resume.public ? (
              <MenuItem onClick={handleShareLink}>
                <ListItemIcon>
                  <LinkIcon className="scale-90" />
                </ListItemIcon>
                <ListItemText>{t('builder.header.menu.share-link')}</ListItemText>
              </MenuItem>
            ) : (
              <Tooltip arrow placement="right" title={t('builder.header.menu.tooltips.share-link') as string}>
                <div>
                  <MenuItem>
                    <ListItemIcon>
                      <LinkIcon className="scale-90" />
                    </ListItemIcon>
                    <ListItemText>{t('builder.header.menu.share-link')}</ListItemText>
                  </MenuItem>
                </div>
              </Tooltip>
            )}

            <Tooltip arrow placement="right" title={t('builder.header.menu.tooltips.delete') as string}>
              <MenuItem onClick={handleDelete}>
                <ListItemIcon>
                  <Delete className="scale-90" />
                </ListItemIcon>
                <ListItemText>{t('builder.header.menu.delete')}</ListItemText>
              </MenuItem>
            </Tooltip>
          </Menu>
        </div>

        <IconButton onClick={toggleRightSidebar}>{right.open ? <ChevronRightIcon /> : <ChevronLeftIcon />}</IconButton>
      </Toolbar>
    </AppBar>
  );
};

export default Header;
