import React from 'react';
import './SkynetExport.css';
import CheckboxTree from 'react-checkbox-tree';
import {connect} from 'react-redux';
import IPCContainer from '../IPCContainer/IPCContainer';
import {notifyApplicationBusy} from '../../redux/actions/common_actions';
import {notifyError, notifyInfo} from '../../redux/actions/error_actions';
import Box from '../../components/UI/Box/Box';
import {displaySkynetExport} from '../../redux/actions/skynet_actions';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import {
  faCheckSquare, faChevronDown,
  faChevronRight, faFile, faFolder, faFolderOpen,
  faHSquare, faMinusSquare, faPlusSquare,
  faSquare
} from '@fortawesome/free-solid-svg-icons';
import Button from '../../components/UI/Button/Button';

const Constants = require('../../constants');

const mapStateToProps = state => {
  return {
    AppBusy: state.common.AppBusy,
  };
};

const mapDispatchToProps = dispatch => {
  return {
    displaySkynetExport: display => dispatch(displaySkynetExport(display)),
    notifyApplicationBusy: busy => dispatch(notifyApplicationBusy(busy, true)),
    notifyError: msg => dispatch(notifyError(msg)),
    notifyInfo: (title, msg) => dispatch(notifyInfo(title, msg)),
  }
};

export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCContainer {
  state = {
    checked: [],
    clicked: {},
    expanded: [],
    nodes: [],
    second_stage: false,
  }

  componentDidMount() {
    this.setRequestHandler(Constants.IPC_Grab_Skynet_Tree_Reply, this.onGrabSkynetTreeReply);
    this.setRequestHandler(Constants.IPC_Export_Skylinks_Reply, this.onExportSkylinksReply);
    this.sendRequest(Constants.IPC_Grab_Skynet_Tree, {Version: this.props.version});
  }

  componentWillUnmount() {
    super.componentWillUnmount();
  }

  createNodes = items => {
    /*
    {
      name: '',
      path: '',
      directory: true/false,
      children: [],
    }
     */
    const ret = [];
    for (const item of items) {
      const treeItem = {
        label: item.name,
        path: item.path,
        value: item.name === '/' ? 0 : item.path ? item.path : JSON.stringify(item),
      };

      if (item.directory) {
        treeItem.children = this.createNodes(item.children);
      }

      ret.push(treeItem);
    }

    return ret;
  }

  handleNavigation = () => {
    if (this.state.second_stage) {
      this.props.notifyApplicationBusy(true);
      this.sendRequest(Constants.IPC_Export_Skylinks, {
        Version: this.props.version,
        Paths: this.state.checked,
      });
    } else {
      if (this.state.checked.length === 0) {
        this.props.notifyError('No files have been checked');
      } else {
        this.setState({
          second_stage: true,
        });
      }
    }
  }

  onExportSkylinksReply = (_, arg) => {
    this.props.notifyApplicationBusy(false);
    if (arg.data.Success) {
      this.setState({
        checked: [],
        clicked: {},
        expanded: [],
        nodes: [],
        second_stage: false,
      }, () => {
        this.props.notifyInfo('Skylink Exports', '!alternate!!copyable!' + JSON.stringify(arg.data.Result.success, null, 2));
        this.sendRequest(Constants.IPC_Grab_Skynet_Tree, {Version: this.props.version});
      });
    } else {
      this.props.notifyError(arg.data.Error);
    }
  }

  onGrabSkynetTreeReply = (_, arg) => {
    if (arg.data.Success) {
      this.setState({
        checked: [],
        expanded: [0],
        nodes: this.createNodes(arg.data.Result),
      });
    } else {
      this.setState({
        checked: [],
        expanded: [],
        nodes: [],
      }, () => {
        this.props.notifyError(arg.data.Error);
      });
    }
  }

  render() {
    return this.props.AppBusy ? (<div/>) : (
      <Box dxDark dxStyle={{
        height: '90vh',
        padding: 'var(--default_spacing)',
        width: 'calc(100vw - (var(--default_spacing) * 4)'
      }}>
        <div
          style={{
            float: 'right',
            margin: 0,
            padding: 0,
            marginTop: '-4px',
            boxSizing: 'border-box',
            display: 'block'
          }}>
          <a href={'#'}
             onClick={() => this.props.displaySkynetExport(false)}
             style={{cursor: 'pointer'}}>X</a>
        </div>
        <h1
          className={'SkynetExportHeading'}>{this.state.second_stage ? 'Verify Exports' : 'Export Files'}</h1>
        <div className={this.state.second_stage ? 'SkynetExportList' : 'SkynetExportTree'}>
          {
            this.state.second_stage ?
              this.state.checked.map(path => {
                return (
                  <input readOnly
                         className={'ConfigurationItemInput'}
                         key={path}
                         style={{width: '100%', marginBottom: 'var(--default_spacing)'}}
                         type={'text'}
                         value={path}/>
                );
              })
              : (
                <CheckboxTree checked={this.state.checked}
                              expanded={this.state.expanded}
                              expandOnClick
                              showExpandAll
                              icons={{
                                check: <FontAwesomeIcon icon={faCheckSquare} fixedWidth
                                                        style={{padding: 0, margin: 0}}/>,
                                uncheck: <FontAwesomeIcon icon={faSquare} fixedWidth
                                                          style={{padding: 0, margin: 0}}/>,
                                halfCheck: <FontAwesomeIcon icon={faHSquare} fixedWidth
                                                            style={{padding: 0, margin: 0}}/>,
                                expandClose: <FontAwesomeIcon icon={faChevronRight} fixedWidth
                                                              style={{padding: 0, margin: 0}}/>,
                                expandOpen: <FontAwesomeIcon icon={faChevronDown} fixedWidth
                                                             style={{padding: 0, margin: 0}}/>,
                                expandAll: <FontAwesomeIcon icon={faPlusSquare} fixedWidth
                                                            style={{padding: 0, margin: 0}}/>,
                                collapseAll: <FontAwesomeIcon icon={faMinusSquare} fixedWidth
                                                              style={{padding: 0, margin: 0}}/>,
                                parentClose: <FontAwesomeIcon icon={faFolder}
                                                              fixedWidth
                                                              color={'var(--heading_text_color)'}
                                                              style={{padding: 0, margin: 0}}/>,
                                parentOpen: <FontAwesomeIcon icon={faFolderOpen}
                                                             fixedWidth
                                                             color={'var(--heading_text_color)'}
                                                             style={{padding: 0, margin: 0}}/>,
                                leaf: <FontAwesomeIcon icon={faFile}
                                                       fixedWidth
                                                       color={'var(--text_color)'}
                                                       style={{padding: 0, margin: 0}}/>
                              }}
                              nodes={this.state.nodes}
                              onClick={clicked => this.setState({clicked})}
                              onCheck={checked => this.setState({checked})}
                              onExpand={expanded => this.setState({expanded})}/>
              )
          }
        </div>
        <div style={{display: 'flex', justifyContent: 'flex-end'}}>
          {
            this.state.second_stage ?
              <Button buttonStyles={{
                height: 'auto',
                marginLeft: 'var(--default_spacing)',
                marginTop: 'var(--default_spacing)',
                width: 'auto'
              }} clicked={() => this.setState({
                second_stage: false,
              })}>{'Back'}</Button> :
              null
          }
          <Button buttonStyles={{
            height: 'auto',
            marginLeft: 'var(--default_spacing)',
            marginTop: 'var(--default_spacing)',
            width: 'auto'
          }}
                  clicked={this.handleNavigation}>{this.state.second_stage ? 'Export' : 'Next'}</Button>
        </div>
      </Box>
    );
  }
});
