import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
  faTrash, faSyncAlt, faEye, faEyeSlash, faUpload, faPlus, faEllipsisV, faFolderPlus,
} from '@fortawesome/free-solid-svg-icons';
import {
  ContextMenu, MenuItem, ContextMenuTrigger, SubMenu,
} from 'react-contextmenu';
import Filters from './Filters';
import LooseFileList from './LooseFileList';
import TopLevelFolderList from './TopLevelFolderList';
import OpenFolderList from './OpenFolderList';
import { loadAuthParam, parseIDToken } from '../logic/auth';
import '../css/User.css';

class User extends Component {
  constructor() {
    super();
    this.state = {
      looseFilesIsDisplayed: true,
    };
  }

  viewToggle = () => {
    const { forwardRef } = this.props;
    const { display } = forwardRef.current.style;
    forwardRef.current.style.display = (display === 'none') ? 'block' : 'none';
  }

  handleIconClick = (event, func) => {
    event.stopPropagation();
    if (func !== undefined) {
      func();
    }
  }

  uploadController = (event, idToken) => {
    event.stopPropagation();
    const uploadedFiles = this.addFiles(event.target, idToken);
    this.uploadFiles(uploadedFiles);
  }

  addFiles = (target, idToken) => {
    const list = [];
    for (let i = 0; i < target.files.length; i++) {
      list[i] = {
        file: target.files[i],
        user: idToken,
      };
    }
    return list;
  }

  uploadFiles = (filesList) => {
    const { fileUpload } = this.props;
    for (let i = 0; i < filesList.length; i++) {
      fileUpload((filesList[i].user), filesList[i].file);
    }
  }

  toggleLoose = () => {
    this.setState((prevState) => ({
      looseFilesIsDisplayed: !prevState.looseFilesIsDisplayed,
    }));
  }

  shareFile = (fileId, newEmail) => {
    const { refreshFunc } = this.props;
    const { userId } = this.props;
    window.gapi.client.drive.permissions.create({
      fileId,
      emailMessage: 'Share Success!',
      sendNotificationEmail: true,
      resource: {
        type: 'user',
        role: 'writer',
        emailAddress: newEmail,
      },
    }).then((response) => {
      refreshFunc(userId);
    }, (error) => {
      alert('Insufficient Permission to Share This File');
    });
  }

  // This is to be used with the decorator func in app
  moveExternal = (fileId, newEmail) => {
    window.gapi.client.drive.permissions.create({
      fileId,
      resource: {
        type: 'user',
        role: 'writer',
        emailAddress: newEmail,
      },
    }).then((response) => {
      if (response.error) {
        console.log(response.error);
      }
      console.log(response);
      window.gapi.client.drive.permissions.update({
        fileId,
        permissionId: response.result.id,
        transferOwnership: true,
        resource: {
          role: 'owner',
        },
      }).then((response) => {
        if (response.error) {
          console.log(response.error);
        }
      });
    });
  }

  create = (fileType) => {
    const { refreshFunc } = this.props;
    const { userId } = this.props;
    let newName = prompt('Enter a Name');
    if (newName === null) { return; }
    if (newName === '') {
      newName = null;
    }
    const reqBody = JSON.stringify({
      mimeType: fileType,
      name: newName,
    });
    window.gapi.client.drive.files.create({
      resource: reqBody,
    }).then((response) => {
      refreshFunc(userId);
    });
  }

  render() {
    const { looseFilesIsDisplayed } = this.state;

    const {
      closePath, filterFunc, idToken, looseFileList, moveExternal,
      moveWithin, openFolder, openFolderList, refreshFunc, removeFunc, sortFunc,
      topLevelFolderList, updatePath, userId,
    } = this.props;

    const { name, email, picture } = parseIDToken(idToken);
    const createFunc = loadAuthParam(email, this.create);
    return (
      <ContextMenuTrigger className="user" id={userId.toString()}>
        <button
          type="button"
          className="user-banner"
          onClick={() => this.viewToggle()}
          onKeyDown={() => this.viewToggle()}
        >
          <img className="profile-picture" src={picture} alt="Account profile" />
          <span className="profile-text">
            {' '}
            <span className="profile-name">{name}</span>
            {' '}
            <span className="profile-email">
              (
              {email}
              )
            </span>
          </span>
          <ContextMenuTrigger className="context-menu" id={userId.toString()} holdToDisplay={0}>
            <FontAwesomeIcon className="fa-ellipsis menu-icon" icon={faEllipsisV} size="lg" onClick={(event) => this.handleIconClick(event, () => {})} title="Options" />
          </ContextMenuTrigger>
        </button>
        <ContextMenu className="context-menu" id={userId.toString()}>
          <MenuItem className="menu-item upload">
            <SubMenu
              className="context-menu sub-menu-upload"
              title={
              (
                <span>
                  <FontAwesomeIcon className="fa-plus menu-icon" icon={faPlus} onClick={(event) => this.handleIconClick(event, () => {})} />
                  Create New...
                </span>
              )
            }
            >
              <MenuItem className="menu-item" onClick={() => createFunc('application/vnd.google-apps.folder', 'New Folder')}>
                <FontAwesomeIcon className="fa-folder menu-icon" icon={faFolderPlus} />
                Folder
              </MenuItem>
              <hr className="divider" />
              <MenuItem className="menu-item" onClick={() => createFunc('application/vnd.google-apps.document', 'New Doc')}>
                <img className="menu-icon" src="https://drive-thirdparty.googleusercontent.com/16/type/application/vnd.google-apps.document" alt="Google Doc icon" />
                Google Doc
              </MenuItem>
              <MenuItem className="menu-item" onClick={() => createFunc('application/vnd.google-apps.spreadsheet', 'New Sheet')}>
                <img className="menu-icon" src="https://drive-thirdparty.googleusercontent.com/16/type/application/vnd.google-apps.spreadsheet" alt="Google Speardsheet icon" />
                Google Sheets
              </MenuItem>
              <MenuItem className="menu-item" onClick={() => createFunc('application/vnd.google-apps.presentation', 'New Presentation')}>
                <img className="menu-icon" src="https://drive-thirdparty.googleusercontent.com/16/type/application/vnd.google-apps.presentation" alt="Google Slides icon" />
                Google Slides
              </MenuItem>
              <MenuItem className="menu-item" onClick={() => createFunc('application/vnd.google-apps.form', 'New Form')}>
                <img className="menu-icon" src="https://drive-thirdparty.googleusercontent.com/16/type/application/vnd.google-apps.form" alt="Google Forms icon" />
                Google Forms
              </MenuItem>
            </SubMenu>
          </MenuItem>
          <label htmlFor={email}>
            <MenuItem className="menu-item">
              <FontAwesomeIcon className="fa-upload menu-icon" icon={faUpload} />
              <input
                type="file"
                id={email}
                className="file-input"
                onChange={(e) => this.uploadController(e, idToken)}
                multiple
              />
              Upload
            </MenuItem>
          </label>
          <MenuItem className="menu-item" onClick={(event) => this.handleIconClick(event, () => this.toggleLoose())}>
            <FontAwesomeIcon className="fa-eye-slash menu-icon" icon={(looseFilesIsDisplayed) ? faEyeSlash : faEye} />
            Toggle Folder View
          </MenuItem>
          <MenuItem className="menu-item" onClick={(event) => this.handleIconClick(event, () => refreshFunc(userId))}>
            <FontAwesomeIcon className="fa-sync menu-icon" icon={faSyncAlt} />
            Refresh Account
          </MenuItem>
          <MenuItem className="menu-item" onClick={(event) => this.handleIconClick(event, () => removeFunc(userId))}>
            <FontAwesomeIcon className="fa-trash menu-icon" icon={faTrash} />
            Remove Account
          </MenuItem>
        </ContextMenu>
        <div style={{ display: 'none' }} className="Files/Folders" ref={this.props.forwardRef}>
          <Filters
            filterFunc={filterFunc}
            sortFunc={sortFunc}
            userId={userId}
          />
          <TopLevelFolderList
            email={email}
            userId={userId}
            topLevelFolderList={topLevelFolderList}
            shareFile={loadAuthParam(email, this.shareFile)}
            moveWithin={moveWithin}
            moveExternal={moveExternal}
            refreshFunc={refreshFunc}
            openFolder={openFolder}
          />
          <OpenFolderList
            email={email}
            userId={userId}
            openFolderList={openFolderList}
            shareFile={loadAuthParam(email, this.shareFile)}
            moveWithin={moveWithin}
            moveExternal={moveExternal}
            refreshFunc={refreshFunc}
            openFolder={openFolder}
            closePath={closePath}
            updatePath={updatePath}
          />
          {looseFilesIsDisplayed && (
            <LooseFileList
              email={email}
              userId={userId}
              looseFileList={looseFileList}
              shareFile={loadAuthParam(email, this.shareFile)}
              moveWithin={moveWithin}
              moveExternal={moveExternal}
              refreshFunc={refreshFunc}
            />
          )}
        </div>
      </ContextMenuTrigger>
    );
  }
}

User.propTypes = {
  closePath: PropTypes.func.isRequired,
  fileUpload: PropTypes.func.isRequired,
  filterFunc: PropTypes.func.isRequired,
  forwardRef: PropTypes.oneOfType([
    PropTypes.func,
    PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
  ]).isRequired,
  idToken: PropTypes.string.isRequired,
  looseFileList: PropTypes.arrayOf(PropTypes.object).isRequired,
  moveExternal: PropTypes.func.isRequired,
  moveWithin: PropTypes.func.isRequired,
  openFolder: PropTypes.func.isRequired,
  openFolderList: PropTypes.arrayOf(PropTypes.object).isRequired,
  refreshFunc: PropTypes.func.isRequired,
  removeFunc: PropTypes.func.isRequired,
  sortFunc: PropTypes.func.isRequired,
  topLevelFolderList: PropTypes.arrayOf(PropTypes.object).isRequired,
  updatePath: PropTypes.func.isRequired,
  userId: PropTypes.number.isRequired,
};

export default User;