/** @jsx jsx */
import { jsx } from '@emotion/core';
import styled from '@emotion/styled';
import { ReactComponent as XIcon } from '../../icons/X.svg';
import { gray200, gray300, gray700, gray800, blue500, gray400, gray600 } from '../../styles/colors_v2';
import { useContext, useCallback, Fragment, useState, useEffect } from 'react';
import { ScreenConfigurationContext } from '../../hooks/useScreenConfiguration';
import { ClearButton, CornerButton, MajorButton } from '../../styles/elements';
import { navHeight, closedToolbarWidth, openToolbarWidth, expandedTrackHeight } from '../../styles/dimensions';
import { ReactComponent as SaveIcon } from '../../icons/Save.svg';
import { ProjectManagementContext } from '../../hooks/useProjectManagement';
import Modal, { ModalBody, ModalButton, ModalTitle } from '../../Modal';
import WalkthroughFlag from '../WalkthroughFlag';
import { WalkthroughContext, WalkthroughStep } from '../../hooks/useWalkthrough';

const MainToolbar = styled.div<{open: boolean}>`
  width: ${({ open }) => open ? openToolbarWidth : closedToolbarWidth}px;
  background-color: ${gray200};
  border-right: 4px solid ${gray300};
  position: relative;
  z-index: 3;
  grid-row-start: 1;
  grid-row-end: 4;
  grid-column: 1;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: space-between;
  ${({ open }) => !open && `
    &:hover {
      color: ${gray800};
      background-color: ${gray600};
      cursor: pointer;
    }
  `}
`;

const ToolbarHeader = styled.div`
  display: grid;
  grid-template-columns: ${closedToolbarWidth}px 1fr;
  padding-right: 10px;
`;

const ToolbarButton = styled(ClearButton)`
  color: inherit;
  width: 100%;
  height: ${navHeight}px;
  padding: 0;
  svg {
    transform: scale(1.25);
  }
  &:hover {
    color: inherit;
  }
  svg * {
    fill: transparent;
    stroke: currentColor;
  }
`;

const Footer = styled.footer`
  font-size: 13px;
  padding: 10px;
  text-align: center;
  a {
    color: inherit;
    &:hover {
      color: ${blue500};
    }
  }
`;

const ButtonWrap = styled.div`
  margin-top: 8px;
  display: flex;
  justify-content: stretch;
  margin-bottom: 8px;
`;

const SaveButton = styled(MajorButton)`
  padding: 8px 12px;
  margin-right: 4px;
  svg * {
    fill: transparent;
    stroke: ${gray800};
  }
`;

const SaveAsButton = styled(MajorButton)`
  padding: 8px 12px;
  background-color: ${gray400};
  &:hover {
    background-color: ${gray600};
  }
  svg * {
    fill: transparent;
    stroke: ${gray800};
  }
`;

const NewProjectButton = styled(MajorButton)`
  width: 100%;
  padding: 8px 12px;
  background-color: ${gray400};
  margin-bottom: 20px;
  &:hover {
    background-color: ${gray600};
  }
`;

const SaveLoadSection = styled.div`
  flex-grow: 1;
  padding: 10px;
`;

const Input = styled.input`
  font-family: inherit;
  background-color: ${gray300};
  width: 100%;
  border-radius: 2px;
  padding: 8px;
  font-size: 24px;
  margin-top: 4px;
  color: ${gray800};
  border: 2px solid transparent;
  margin-bottom: 16px;
  &:focus, &:active {
    outline: none;
    border: 2px solid ${blue500};
  }
`;

const NameReadout = styled.h2`
  font-size: 24px;
  padding: 8px 0;
  color: ${gray800};
`;

const ProjectList = styled.div`
  margin-top: 12px;
  > * {
    min-width: 60%;
    text-align: left;
    margin-bottom: 10px;
  }
`;
const ProjectName = styled.h3``;
const Subheading = styled.h4`
  font-size: 13px;
  font-weight: 600;
  color: ${gray700};
`;
const ProjectButton = styled(CornerButton)`
  justify-content: flex-start;
`;

const Message = styled.h5`
  color: ${gray800};
  font-size: 16px;
  min-height: 24px;
`;

const LOAD_NEW_PROJECT_OBJECT = {};

const Toolbar = () => {
  const screenConfiguration = useContext(ScreenConfigurationContext);
  const projectManagement = useContext(ProjectManagementContext);

  const openCommandView = useCallback(
    () => {
      if (!screenConfiguration.toolbarOpen) {
        screenConfiguration.setToolbarOpen(true);
      }
    },
    [screenConfiguration]
  );

  const closeCommandView = useCallback(
    () => {
      if (screenConfiguration.toolbarOpen) {
        screenConfiguration.setToolbarOpen(false);
      }
    },
    [screenConfiguration]
  );

  const [projectName, setProjectName] = useState(projectManagement.currentProjectName || 'Untitled');
  const [showNameInput, setShowNameInput] = useState(!projectManagement.currentProjectName);
  const onClickSave = useCallback(() => {
    if (showNameInput) {
      projectManagement.saveProjectAs(projectName);
      setShowNameInput(false);
    } else {
      projectManagement.saveProject();
    }
  }, [projectManagement, projectName, setShowNameInput, showNameInput]);

  const onClickSaveAs = useCallback(() => {
    setProjectName(projectManagement.currentProjectName || 'Untitled');
    setShowNameInput(true);
  }, [projectManagement, setProjectName, setShowNameInput]);

  const [projectToLoad, setProjectToLoad] = useState<string | typeof LOAD_NEW_PROJECT_OBJECT | null>(null);

  const onLoadProject = useCallback((name: string) => {
    if (projectManagement.hasChanges && !projectManagement.isEmpty) {
      setProjectToLoad(name);
    } else {
      setShowNameInput(false);
      projectManagement.loadProject(name);
    }
  }, [projectManagement, setShowNameInput, setProjectToLoad]);

  const onClickStartNew = useCallback(() => {
    if (projectManagement.hasChanges && !projectManagement.isEmpty) {
      setProjectToLoad(LOAD_NEW_PROJECT_OBJECT);
    } else {
      projectManagement.startNew();
    }
  }, [projectManagement, setProjectToLoad]);

  const onConfirmClose = useCallback(
    () => {
      if (typeof projectToLoad === 'string') {
        projectManagement.loadProject(projectToLoad);
      } else if (projectToLoad === LOAD_NEW_PROJECT_OBJECT) {
        projectManagement.startNew();
      }
      setProjectToLoad(null);
    },
    [projectManagement, projectToLoad, setProjectToLoad]
  );

  const walkthrough = useContext(WalkthroughContext);

  useEffect(() => {
    if (screenConfiguration.toolbarOpen) {
      walkthrough.seeSaveProject();
    }
  }, [screenConfiguration, walkthrough]);

  return (
    <MainToolbar open={screenConfiguration.toolbarOpen} onClick={openCommandView}>
      <WalkthroughFlag
        step={WalkthroughStep.SaveProject}
        style={{ left: 'calc(100% - 12px)', top: navHeight + expandedTrackHeight }}
        anchorStyle={{ left: 5, top: '50%', marginTop: -11 }}
      >
        Click over here to save and load projects!
      </WalkthroughFlag>
      {
        (projectToLoad) && (
        <Modal maxWidth={400}>
          <ModalTitle>Are you sure?</ModalTitle>
          <ModalBody centered>
            {projectManagement.currentProjectName ? `"${projectManagement.currentProjectName}"` : 'Your project'} has unsaved changes.
          </ModalBody>
          <ModalButton onClick={() => setProjectToLoad(null)}>Whoops. Cancel.</ModalButton>
          <ModalButton onClick={onConfirmClose}>That's ok. Close it.</ModalButton>
        </Modal>
      )}
      {
        !screenConfiguration.toolbarOpen
          ? <ToolbarButton><SaveIcon /></ToolbarButton>
          : (
            <Fragment>
              <ToolbarHeader>
                <ToolbarButton onClick={closeCommandView}><XIcon /></ToolbarButton>
              </ToolbarHeader>
              <SaveLoadSection>
                {!projectManagement.isEmpty && (
                  <Fragment>
                    <Subheading>{showNameInput ? 'Name Your Project' : 'Current Project'}</Subheading>
                    {showNameInput && <Input autoFocus type="text" value={projectName || ''} onChange={(e) => setProjectName(e.currentTarget.value)} />}
                    {!showNameInput && <NameReadout>{projectManagement.currentProjectName}</NameReadout>}
                    <ButtonWrap>
                      <SaveButton onClick={onClickSave}>
                        <SaveIcon />
                        Save
                      </SaveButton>
                      {!showNameInput && (
                        <SaveAsButton onClick={onClickSaveAs}>
                          <SaveIcon />
                          Save As
                        </SaveAsButton>
                      )}
                      {showNameInput && projectManagement.currentProjectName && (
                        <SaveAsButton onClick={() => setShowNameInput(false)}>
                          <XIcon />
                          Cancel
                        </SaveAsButton>
                      )}
                    </ButtonWrap>
                    <Message>{projectManagement.hasChanges && "You have unsaved changes"}</Message>
                    <Message>{projectManagement.message}</Message>
                  </Fragment>
                )}
                <Subheading>My Projects</Subheading>
                <ProjectList>
                  {projectManagement.projectList.length === 0 && <Message>Once you save a project, it will appear here!</Message>}
                  {projectManagement.projectList.map((name) => (
                    <ProjectButton key={name} onClick={() => onLoadProject(name)}>
                      <ProjectName>{name}</ProjectName>
                    </ProjectButton>
                  ))}
                </ProjectList>
              </SaveLoadSection>
              <Footer>
                {<NewProjectButton onClick={onClickStartNew}>Start a New Project</NewProjectButton>}
                <div>© 2021&nbsp;&nbsp;|&nbsp;&nbsp;Created by <a href="https://github.com/TheActualWalko/">Sam Watkinson</a></div>
              </Footer>
            </Fragment>
          )
      }
    </MainToolbar>
  );
}

export default Toolbar;
