import { Button, COLORS, Dialog, Flex, Flow, Item, Labeled, TextInput } from "@heydovetail/ui-components";
import React from "react";

export interface LinkDetails {
  text: string;
  url: string;
}

interface Props {
  editable: boolean;
  onDismiss: () => void;
  onSave: (newLink: LinkDetails) => void;
  text: string;
  url?: string;
}

interface State {
  draftUrl: string;
  draftText: string;
}

export class LinkEditorModal extends React.PureComponent<Props, State> {
  public state: State = {
    draftUrl: urlOrDefault(this.props.url),
    draftText: this.props.text
  };

  public componentWillReceiveProps(newProps: Props) {
    // Preserve any edits that have been made to the text / url, otherwise take
    // the new values. The scenario this intended for is when the link editor is
    // open, but the link text in the document changes (e.g. via collaborator or
    // local user).
    const { draftUrl, draftText } = this.state;
    this.setState({
      draftUrl: draftUrl === this.props.url ? urlOrDefault(newProps.url) : draftUrl,
      draftText: draftText === this.props.text ? newProps.text : draftText
    });
  }

  public render() {
    const { editable, onDismiss } = this.props;
    const isExisting = this.props.url !== undefined;

    return (
      <Dialog onDismiss={onDismiss} title={isExisting ? "Edit link" : "Create link"}>
        <form onSubmit={this.handleSubmit}>
          <Flex styled={{ gap: 32, layout: "column" }}>
            <Item>
              <Labeled text="Link URL">
                <TextInput disabled={!editable} autofocus onChange={this.handleUrlChange} value={this.state.draftUrl} />
              </Labeled>
            </Item>
            <Item>
              <Labeled text="Text to display">
                <TextInput disabled={!editable} onChange={this.handleTextChange} value={this.state.draftText} />
              </Labeled>
            </Item>
            <Item>
              <Flow>
                <Item>
                  <Button color={COLORS.purple} type="submit" disabled={!editable}>
                    Save
                  </Button>
                </Item>
                <Item>
                  <Button onClick={onDismiss}>Cancel</Button>
                </Item>
              </Flow>
            </Item>
          </Flex>
        </form>
      </Dialog>
    );
  }

  private readonly handleSubmit: React.FormEventHandler = e => {
    e.preventDefault();
    if (this.props.editable) {
      const hasChanges = this.state.draftText !== this.props.text || this.state.draftUrl !== this.props.url;
      if (hasChanges) {
        this.props.onSave({
          text: this.state.draftText,
          url: this.state.draftUrl
        });
      } else {
        this.props.onDismiss();
      }
    }
  };

  private readonly handleTextChange: React.ChangeEventHandler<HTMLInputElement> = e => {
    this.setState({ draftText: e.target.value });
  };

  private readonly handleUrlChange: React.ChangeEventHandler<HTMLInputElement> = e => {
    this.setState({ draftUrl: e.target.value });
  };
}

function urlOrDefault(url: string | undefined): string {
  return url !== undefined ? url : "";
}
