import React, { Component } from 'react';
import _ from 'lodash';
import moment from 'moment';
import Mousetrap from 'mousetrap';
import classnames from 'classnames';

import { Sigil } from '/components/lib/icons/sigil';

import { uuid, uxToHex } from '/lib/util';

const DEFAULT_INPUT_HEIGHT = 28;

export class ChatInput extends Component {

  constructor(props) {
    super(props);

    this.state = {
      message: '',
      textareaHeight: DEFAULT_INPUT_HEIGHT
    };

    this.textareaRef = React.createRef();

    this.messageSubmit = this.messageSubmit.bind(this);
    this.messageChange = this.messageChange.bind(this);
                         // Call once per frame @ 60hz
    this.textareaInput = _.debounce(this.textareaInput.bind(this), 16);

    // perf testing:
    /*let closure = () => {
      let x = 0;
      for (var i = 0; i < 30; i++) {
        x++;
        props.api.chat.message(
          props.station,
          `~${window.ship}`,
          Date.now(),
          {
            text: `${x}`
          }
        );
      }
      setTimeout(closure, 1000);
    };
    this.closure = closure.bind(this);*/

    moment.updateLocale('en', {
        relativeTime : {
            past: function(input) {
              return input === 'just now'
                ? input
                : input + ' ago'
            },
            s  : 'just now',
            future: "in %s",
            ss : '%d sec',
            m:  "a minute",
            mm: "%d min",
            h:  "an hr",
            hh: "%d hrs",
            d:  "a day",
            dd: "%d days",
            M:  "a month",
            MM: "%d months",
            y:  "a year",
            yy: "%d years"
        }
    });
  }

  bindShortcuts() {
    Mousetrap(this.textareaRef.current).bind('enter', e => {
      e.preventDefault();
      e.stopPropagation();

      this.messageSubmit(e);
    });
  }

  messageChange(event) {
    this.setState({
      message: event.target.value
    });
  }

  textareaInput() {
    const newHeight = this.textareaRef.current.scrollHeight < DEFAULT_INPUT_HEIGHT * 8
      ? `${this.textareaRef.current.scrollHeight}px`
      : `${DEFAULT_INPUT_HEIGHT * 8}px`

    this.setState({
      textareaHeight: newHeight
    });
  }

  getLetterType(letter) {
    if (letter[0] === '#') {
      letter = letter.slice(1);
      // remove insignificant leading whitespace.
      // aces might be relevant to style.
      while (letter[0] === '\n') {
        letter = letter.slice(1);
      }

      return {
        code: {
          expression: letter,
          output: undefined
        }
      }
    } else if (letter[0] === '@') {
      letter = letter.slice(1);
      // remove insignificant leading whitespace.
      // aces might be relevant to style.
      while (letter[0] === '\n') {
        letter = letter.slice(1);
      }

      return {
        me: letter
      }
    } else if (this.isUrl(letter)) {
       return {
        url: letter
      }
    } else {
      return {
        text: letter
      }
    }
  }

  isUrl(string) {
    try {
      let websiteTest = new RegExp(''
        + /[(http(s)?):\/\/(www\.)?a-zA-Z0-9@:%._\+~#=]{2,256}/.source
        + /\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/.source
      );
      return websiteTest.test(string);
    } catch (e) {
      return false;
    }
  }

  messageSubmit() {
    const { props, state } = this;

    if (state.message === '') {
      return;
    }

    let message = [];
    state.message.split(" ").map((each) => {
      if (this.isUrl(each)) {
        if (message.length > 0) {
          message = message.join(" ");
          message = this.getLetterType(message);
          props.api.chat.message(
            props.station,
            `~${window.ship}`,
            Date.now(),
            message
          );
          message = [];
        }
        let URL = this.getLetterType(each);
        props.api.chat.message(
          props.station,
          `~${window.ship}`,
          Date.now(),
          URL
        );
      }
      else {
        return message.push(each);
      }
    })

    if (message.length > 0) {
      message = message.join(" ");
      message = this.getLetterType(message);
      props.api.chat.message(
        props.station,
        `~${window.ship}`,
        Date.now(),
        message
      );
      message = [];
    }

    // perf: setTimeout(this.closure, 2000);

    this.setState({
      message: '',
      textareaHeight: DEFAULT_INPUT_HEIGHT
    });
  }

  readOnlyRender() {
    const { props } = this;
    let color = !!props.ownerContact
      ? uxToHex(props.ownerContact.color) : '#000000';

    let sigilClass = !!props.ownerContact
      ? "" : "mix-blend-diff";

    return (
      <div className="pa3 cf flex black bt b--gray4 o-50">
        <div className="fl" style={{
          marginTop: 4,
          flexBasis: 24,
          height: 24
        }}>
          <Sigil
            ship={window.ship}
            size={24}
            color={`#${color}`}
            classes={sigilClass}
          />
        </div>
        <div className="fr h-100 flex" style={{ flexGrow: 1, height: 28, paddingTop: 6, resize: "none" }}>
          <p className="pl3">This chat is read only and you cannot post.</p>
        </div>
      </div>
    );
  }

  writeAccessRender() {
    const { props, state } = this;

    let color = !!props.ownerContact
      ? uxToHex(props.ownerContact.color) : '#000000';

    let sigilClass = !!props.ownerContact
      ? "" : "mix-blend-diff";

    this.bindShortcuts();

    return (
      <div className="pa3 cf flex black white-d bt b--gray4 b--gray1-d bg-white bg-gray0-d"
      style={{ flexGrow: 1 }}>
        <div
          className="fl"
          style={{
            marginTop: 4,
            flexBasis: 24,
            height: 24
          }}>
          <Sigil
            ship={window.ship}
            size={24}
            color={`#${color}`}
            classes={sigilClass}
            />
        </div>
        <div className="fr h-100 flex bg-gray0-d" style={{ flexGrow: 1 }}>
          <textarea
            className={"pl3 bn bg-gray0-d white-d"}
            style={{ flexGrow: 1, height: state.textareaHeight, paddingTop: 6, resize: "none" }}
            autoCapitalize="none"
            autoFocus={(
              /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(
              navigator.userAgent
            )) ? false : true}
            ref={this.textareaRef}
            placeholder={props.placeholder}
            value={state.message}
            onChange={this.messageChange}
            onInput={this.textareaInput}
          />
        </div>
      </div>
    );
  }

  render() {
    const { props, state } = this;

    let writePermission = props.permissions[`/chat${props.station}/write`];
    if (writePermission) {
      if (writePermission.kind === 'black') {
        // black
        if (writePermission.who.has(window.ship)) {
          return this.readOnlyRender();
        } else {
          return this.writeAccessRender();
        }
      } else if (writePermission.kind === 'white') {
        // white
        if (writePermission.who.has(window.ship)) {
          return this.writeAccessRender();
        } else {
          return this.readOnlyRender();
        }
      }
    } else {
      return this.writeAccessRender();
    }
  }
}

@@ -4617,33 +4617,32 @@
 ntact.color) : '
-#
 000000';%0A%0A    le
@@ -5429,17 +5429,16 @@
 lor) : '
-#
 000000';

remove "#" from fallback sigil color