import * as React from 'react'
import { Confirm, Table, Input, Button, Icon, Dropdown, Loader, Dimmer } from 'semantic-ui-react';
import moment = require('moment');

export interface UserTableRowProps {
  id: string,
  name: string,
  email: string,
  createdAt: Date,
  lastLogin: Date,
  profileImageUrl: string,
  roleIds: string[],
  roles: any[],

  onEditUser: Function,
  onDeleteUser: Function,
}

export default class UserTableRow extends React.Component<UserTableRowProps> {
  private nameInputContainer: HTMLDivElement;
  private nameInput: Input;

  state = {
    editedRoleIds: null,

    editedName: this.props.name,
    isEditing: false,
    isDeleting: false,
    isBusy: false
  }

  componentDidMount() {
    document.addEventListener('mousedown', this.handleMouseDown, false);
  }

  componentWillUnmount() {
    document.removeEventListener('mousedown', this.handleMouseDown, false);
  }

  private handleMouseDown = (e) => {
    if (this.nameInputContainer && this.nameInputContainer.contains(e.target)) {
      return;
    }

    if (this.nameInput) {
      this.toggleEditName(null);
    }
  }

  private prepareItem() {
    return {
      id: this.props.id,
      email: this.props.email,
      name: this.state.editedName,
      createdAt: this.props.createdAt,
      lastLogin: this.props.lastLogin,
      profileImageUrl: this.props.profileImageUrl,
      roleIds: this.state.editedRoleIds || this.props.roleIds,
    }
  }

  private onCancelDelete = () => {
    this.setState({ isDeleting: false })
  }

  private onConfirmDelete = async () => {
    this.setState({ isDeleting: null, isBusy: true })

    const itemToDelete = this.prepareItem()
    try { this.props.onDeleteUser && await this.props.onDeleteUser(itemToDelete); }
    catch (e) { }

    this.setState({ isBusy: false })
  }

  onNameChanged = (e) => {
    const name = e.target.value;
    this.setState({ editedName: name });
  }

  editItemName = async () => {
    this.setState({ isBusy: true })
    const itemToEdit = this.prepareItem();

    this.toggleEditName(null);

    try { this.props.onEditUser && await this.props.onEditUser(itemToEdit) }
    catch (e) { }

    this.setState({ isBusy: false })
  }

  toggleEditName = (editMode: boolean) => {
    this.setState({ isEditing: editMode })
    if (editMode === true) {
      this.setState({ editedName: this.props.name });
      setTimeout(() => {
        if (this.nameInput) {
          this.nameInput.select()
        }
      }, 300)
    } else {
      this.nameInput = null;
    }
  }

  onEditNameKeyPress = (e) => {
    if (e.charCode === 13 || e.keyCode === 13) {
      this.editItemName();
    }
  }

  onDeleteItem = () => {
    this.setState({ isDeleting: true })
  }

  renderItemRole = () => {
    const roleOptions = this.props.roles.map((r) => { return { key: r.id, text: r.name, value: r.id } })
    return (
      <Dropdown
        // button
        // className='icon'
        floating
        multiple
        labeled
        disabled={this.state.isBusy}
        closeOnChange
        onChange={(_, data) => this.onRolesChanged(data.value)}
        // onClose={(_, data) => this.onRolesClosed(data.value)}
        value={this.props.roleIds}
        options={roleOptions}
        text='Select role'
      />
    )
  }

  onRolesChanged = (roles) => {
    this.setState({ editedRoleIds: roles }, async () => {
      const itemToEdit = this.prepareItem();
      this.setState({ isBusy: true })
      this.props.onEditUser && await this.props.onEditUser(itemToEdit)
      this.setState({ isBusy: false })
    })
  }

  render() {
    const { isEditing, isDeleting, editedName } = this.state;
    const { email, createdAt, profileImageUrl, lastLogin, name } = this.props;
    const deleteContent = isDeleting && `You are about to remove ${name} from this account. Are you sure?`

    return (
      <Table.Row className="user-row" disabled={this.state.isBusy}>
        <Table.Cell width="1"><img className="avatar" alt="profile" src={profileImageUrl} /></Table.Cell>
        <Table.Cell>
          <div>
            {isEditing ?
              <div ref={(c) => { this.nameInputContainer = c; }}>
                <Input value={editedName}
                  className="name-input"
                  ref={(input) => { this.nameInput = input; }}
                  onChange={this.onNameChanged}
                  onKeyPress={this.onEditNameKeyPress} />
              </div>
              :
              <p onMouseUp={() => this.toggleEditName(true)} className="name">{name}</p>
            }
            <p className="email">{email}</p>
          </div>
        </Table.Cell>

        {this.props.roles && this.props.roles.length > 0 &&
          <Table.Cell>
            {this.renderItemRole()}
          </Table.Cell>
        }

        <Table.Cell>
          <div>
            <p className="joined-date">{createdAt ? moment(createdAt).format('LLLL') : 'N/A'}</p>
            <p className="joined-label">Joined team</p>
          </div>
        </Table.Cell>

        <Table.Cell>
          <div>
            <p className="last-login-date">{lastLogin ? moment(lastLogin).format('LLLL') : 'N/A'}</p>
            <p className="last-login-label">Last login</p>
          </div>
        </Table.Cell>
        <Table.Cell>
          <Button className="delete-user-button" icon onClick={() => this.onDeleteItem()}>
            <Icon className="delete-user-icon" name='trash' />
          </Button>
        </Table.Cell>
        <Table.Cell width="1">
          {this.state.isBusy && <Loader size='mini'>Loading</Loader>}
        </Table.Cell>
        {isDeleting && <Confirm
          open={isDeleting}
          header="Delete team member"
          content={deleteContent}
          cancelButton='Never mind'
          confirmButton="Let's do it"
          onCancel={this.onCancelDelete}
          onConfirm={this.onConfirmDelete}
        />}
      </Table.Row>
    )
  }
}
