/** @jsx jsx */
import { jsx } from '@emotion/core';
import styled from '@emotion/styled';
import { Fragment, useContext, useEffect, useState } from 'react';
import BrowserCompatibilityContext, { BrowserCompatibilityClass } from './hooks/useBrowserCompatibility';
import Modal, { ModalBody, ModalButton, ModalTitle } from './Modal';
import { red500, gray100, gray800, blue500, gray700, blue300 } from './styles/colors_v2';

const AlertWrapper = styled.div`
  background-color: ${red500};
  padding: 2px 10px;
  border-radius: 10px;
  font-size: 13px;
  color: ${gray100};
`;

const WarningContentWrapper = styled.div``;

const Graphic = styled.div`
  width: 100%;
  height: 228px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
`;

const PhoneBody = styled.div`
  width: 150px;
  height: 100%;
  background-color: ${gray100};
  position: relative;
  border-radius: 20px;
  overflow: hidden;
  > div {
    border-radius: 7px;
    > div {
      transform-origin: 66px 96px;
      transform: rotate(-5deg);
    }
  }
  &:after {
    content: '';
    display: block;
    background-color: ${gray100};
    position: absolute;
    top: 0;
    left: 40px;
    right: 40px;
    height: 30px;
    border-radius: 8px;
  }
`;

const ComputerBody = styled.div`
  width: 256px;
  height: 160px;
  margin-bottom: 20px;
  background-color: ${gray100};
  position: relative;
  border-radius: 6px;
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
  &:after {
    content: '';
    display: block;
    position: absolute;
    bottom: -28px;
    left: 0;
    right: 0;
    height: 28px;
    background-color: ${gray800};
    border-bottom-left-radius: 6px;
    border-bottom-right-radius: 6px;
  }
`;

const Screen = styled.div`
  position: absolute;
  top: 13px;
  left: 13px;
  right: 13px;
  bottom: 13px;
  background-color: ${blue300};
  overflow: hidden;
  color: ${blue500};
  > div {
    position: absolute;
    top: 0;
    left: 0;
    width: 230px;
    word-wrap: break-word;
    transform-origin: 115px 60px;
    transform: rotate(-5deg);
  }
`;

const StandBack = styled.div`
  width: 80px;
  height: 32px;
  background-color: ${gray700};
`;

const StandBase = styled.div`
  width: 128px;
  height: 12px;
  background-color: ${gray800};
  border-radius: 6px;
`;

const MobileWarning = ({ onClose }: { onClose: () => void }) => {
  const [phoneText, setPhoneText] = useState('a');
  useEffect(() => {
    const frame = requestAnimationFrame(() => {
      if (phoneText.length > 11 * 24) {
        setPhoneText('a');
      } else {
        setPhoneText(phoneText + 'a');
      }
    });
    return () => cancelAnimationFrame(frame);
  }, [phoneText, setPhoneText]);
  return (
    <WarningContentWrapper>
      <ModalTitle>WavTool reeeeally doesn't work on mobile.</ModalTitle>
      <Graphic>
        <PhoneBody>
          <Screen>
            <div>{phoneText}</div>
          </Screen>
        </PhoneBody>
      </Graphic>
      <ModalBody>
        It looks like you're using a mobile device. (If you're not, please ignore this message.)
      </ModalBody>
      <ModalBody>
        WavTool does not go well with mobile. You're welcome to continue, but your experience is virtually certain to be unpleasant.
      </ModalBody>
      <ModalBody>
        Please consider coming back on a bigger, clunkier machine. (Sorry.)
      </ModalBody>
      <ModalButton onClick={onClose}>Continue</ModalButton>
    </WarningContentWrapper>
  );
};

const SafariWarning = ({ onClose }: { onClose: () => void }) => {
  const [computerText, setComputerText] = useState('a');
  useEffect(() => {
    const frame = requestAnimationFrame(() => {
      if (computerText.length > 7 * 25) {
        setComputerText('a');
      } else {
        setComputerText(computerText + 'a');
      }
    });
    return () => cancelAnimationFrame(frame);
  }, [computerText, setComputerText])
  return (
    <WarningContentWrapper>
      <ModalTitle>WavTool is bad on Safari.</ModalTitle>
      <Graphic>
        <ComputerBody>
          <Screen>
            <div>{computerText}</div>
          </Screen>
        </ComputerBody>
        <StandBack />
        <StandBase />
      </Graphic>
      <ModalBody>
        It looks like you're using Safari. (If you're not, please ignore this message.)
      </ModalBody>
      <ModalBody>
        We're not sure what we did to offend Safari, but it <em>really</em> does not play well WavTool. You are welcome to continue, but your experience may suffer.
      </ModalBody>
      <ModalBody>
        For a good time with WavTool, consider <a href="https://www.google.com/chrome/">Chrome</a> or <a href="https://www.firefox.com/">Firefox</a>.
      </ModalBody>
      <ModalButton onClick={onClose}>Continue</ModalButton>
    </WarningContentWrapper>
  );
};

const OldWarning = ({ onClose }: { onClose: () => void }) => (
  <WarningContentWrapper>
    <ModalTitle>Whoa. Where did you get this thing?</ModalTitle>
    <ModalBody>
      Your OS is not one we expected to ever run WavTool.
    </ModalBody>
    <ModalBody>
      You seem pretty cool, and we don't want you to have a bad impression. WavTool is probably gonna break right now. But maybe try coming back on a newer machine?
    </ModalBody>
    <ModalButton onClick={onClose}>Continue</ModalButton>
  </WarningContentWrapper>
);

const warnings = {
  [BrowserCompatibilityClass.Mobile]: MobileWarning,
  [BrowserCompatibilityClass.Safari]: SafariWarning,
  [BrowserCompatibilityClass.Old]: OldWarning,
}

export default () => {
  const compatibilityClass = useContext(BrowserCompatibilityContext);
  const Warning = (warnings as any)[compatibilityClass] as typeof SafariWarning | undefined;
  const [modalOpen, setModalOpen] = useState(!!Warning);
  if (Warning) {
    return (
      <Fragment>
        <AlertWrapper onClick={() => setModalOpen(true)}>
          WavTool may struggle on this browser
        </AlertWrapper>
        {
          modalOpen && (
            <Modal>
              <Warning onClose={() => setModalOpen(false)} />
            </Modal>
          )
        }
      </Fragment>
    )
  } else {
    return null;
  }
}
