import { exhausted } from "@heydovetail/assert";
import { BREAKPOINT_PHONE, Portal } from "@heydovetail/ui-components";
import { EditorView } from "prosemirror-view";
import React from "react";
import MediaQuery from "react-responsive";
import { dismissEditorOrComposer, editTextLink, removeLink, saveTextLink } from "../commands";
import { LinkPluginStateType, getPluginStateOrThrow } from "../LinkPlugin";
import { CenteredAtPoint } from "./CenteredAtPoint";
import { CenteredScreenBottom } from "./CenteredScreenBottom";
import { LinkEditorModal } from "./LinkEditorModal";
import { LinkEditorPanel } from "./LinkEditorPanel";

const TEXT_BOTTOM_PADDING = 5;

export const LinkEditor: React.SFC<{ view: EditorView }> = ({ view }) => {
  const linkState = getPluginStateOrThrow(view.state);
  const editable = view.props.editable != null ? view.props.editable(view.state) : true;

  switch (linkState.type) {
    case LinkPluginStateType.IDLE:
      return null;
    case LinkPluginStateType.SHOW_COMPOSER: {
      const { text } = linkState.draft;
      return (
        <LinkEditorModal
          editable={editable}
          onSave={newLink => {
            saveTextLink(view.state, newLink, view.dispatch);
            view.focus();
          }}
          onDismiss={() => {
            dismissEditorOrComposer(view.state, view.dispatch);
            view.focus();
          }}
          text={text}
        />
      );
    }
    case LinkPluginStateType.SHOW_DETAIL: {
      const {
        range: { from, to },
        url
      } = linkState.link;
      const start = view.coordsAtPos(from);
      const end = view.coordsAtPos(to);

      // Find a center-ish x position from the selection endpoints (when
      // crossing lines, end may be more to the left)
      const screenLeft = Math.max((start.left + end.left) / 2, start.left + 3);
      const screenTop = start.top + TEXT_BOTTOM_PADDING;

      const panel = (
        <LinkEditorPanel
          editable={editable}
          onEditClick={() => {
            editTextLink(view.state, view.dispatch);
          }}
          onRemoveClick={() => {
            removeLink(view.state, view.dispatch);
            view.focus();
          }}
          url={url}
        />
      );

      return (
        <Portal>
          <MediaQuery maxWidth={BREAKPOINT_PHONE - 1}>
            <CenteredScreenBottom>{panel}</CenteredScreenBottom>
          </MediaQuery>
          <MediaQuery minWidth={BREAKPOINT_PHONE}>
            <CenteredAtPoint screenLeft={screenLeft} screenTop={screenTop}>
              {panel}
            </CenteredAtPoint>
          </MediaQuery>
        </Portal>
      );
    }
    case LinkPluginStateType.SHOW_EDITOR: {
      const { url, text } = linkState.link;
      return (
        <LinkEditorModal
          editable={editable}
          onSave={newLink => {
            saveTextLink(view.state, newLink, view.dispatch);
            view.focus();
          }}
          onDismiss={() => {
            dismissEditorOrComposer(view.state, view.dispatch);
            view.focus();
          }}
          url={url}
          text={text}
        />
      );
    }
    default:
      throw exhausted(linkState);
  }
};
