import React from 'react'
import {connect} from 'react-redux';
import './SkynetImport.css'
import Box from '../../components/UI/Box/Box';
import Button from '../../components/UI/Button/Button';
import {displaySkynetImport} from '../../redux/actions/skynet_actions';
import ImportList from './ImportList/ImportList'
import IPCContainer from '../IPCContainer/IPCContainer';
import {notifyApplicationBusy} from '../../redux/actions/common_actions';
import {
  notifyError,
  notifyInfo
} from '../../redux/actions/error_actions';

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

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

const mapDispatchToProps = dispatch => {
  return {
    displaySkynetImport: display => dispatch(displaySkynetImport(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 = {
    import_text: '',
    imports_array: [],
    second_stage: false,
  };

  componentDidMount() {
    this.setRequestHandler(Constants.IPC_Import_Skylinks_Reply, this.onImportSkylinksReply);
  }

  componentWillUnmount() {
    super.componentWillUnmount();
  }

  displaySyntax = () => {
    const msg = '!alternate!To import Skylinks into the root directory, list each Skylink on a new line:\n' +
      '  AACeCiD6WQG6DzDcCdIu3cFPSxMUMoQPx46NYSyijNMKUA\n' +
      '  AACyjmDGoHqY7mTaxi-rkpnKUJGZK1B4UhrF74Nv6tY6Cg\n' +
      '\n' +
      'To import Skylinks into new or existing directories, use the following syntax:\n' +
      '  directory="/my/sub/dir",skylink="AACeCiD6WQG6DzDcCdIu3cFPSxMUMoQPx46NYSyijNMKUA"\n' +
      '  directory="/my/sub/dir2",skylink="AACyjmDGoHqY7mTaxi-rkpnKUJGZK1B4UhrF74Nv6tY6Cg"\n' +
      '\n' +
      'You can also specify a password if this in an encrypted Repertory Skylink:\n' +
      '  directory="/my/sub/dir",skylink="AACeCiD6WQG6DzDcCdIu3cFPSxMUMoQPx46NYSyijNMKUA",token="My Password"\n' +
      '  directory="/my/sub/dir",skylink="AACyjmDGoHqY7mTaxi-rkpnKUJGZK1B4UhrF74Nv6tY6Cg",token="My Password"\n' +
      '\n' +
      'To import Skylinks using JSON syntax:\n' +
      '  [\n' +
      '     {\n' +
      '        "directory": "/",\n' +
      '        "skylink": "AACeCiD6WQG6DzDcCdIu3cFPSxMUMoQPx46NYSyijNMKUA",\n' +
      '        "token": "My Password"\n' +
      '     },\n' +
      '     {\n' +
      '        "directory": "/my/sub/dir",\n' +
      '        "skylink": "AACyjmDGoHqY7mTaxi-rkpnKUJGZK1B4UhrF74Nv6tY6Cg",\n' +
      '        "token": "My Password"\n' +
      '     }\n' +
      '  ]';
    this.props.notifyInfo('Import Syntax', msg)
  }

  handleNavigation = () => {
    if (this.state.second_stage) {
      try {
        this.props.notifyApplicationBusy(true);
        this.sendRequest(Constants.IPC_Import_Skylinks, {
          Version: this.props.version,
          JsonArray: this.state.imports_array,
        });
      } catch (e) {
        this.props.notifyApplicationBusy(false);
        this.props.notifyError(e);
      }
    } else {
      const items = this.state.import_text.split('\n');
      let importsArray = [];
      try {
        for (let item of items) {
          item = item.trim();
          if (item.startsWith('[')) {
            importsArray = JSON.parse(this.state.import_text.trim());
            break;
          } else if (item.indexOf('=') >= 0) {
            const parts = item.split(',')
            let importItem = {
              directory: '/',
              skylink: '',
              token: '',
            };
            for (let part of parts) {
              part = part.trim();
              const pair = part.split('=');
              if (pair.length !== 2) {
                throw new Error('Invalid syntax for import: directory="",skylink="",token=""');
              }
              importItem = {
                ...importItem,
                [pair[0].trim()]: pair[1].trim().replace(/"/g, ''),
              };
            }
            if (!importItem.skylink) {
              throw new Error('Invalid syntax for import: directory="",skylink="",token=""');
            }
            importsArray.push(importItem);
          } else if (item.length > 0) {
            importsArray.push({
              directory: '/',
              skylink: item,
            });
          }
        }

        if (importsArray.length === 0) {
          throw new Error('Nothing to import');
        }
        this.setState({
          imports_array: importsArray,
          second_stage: true,
        });
      } catch (e) {
        this.props.notifyError(e);
      }
    }
  }

  onImportSkylinksReply = (_, arg) => {
    this.props.notifyApplicationBusy(false);
    if (arg.data.Success) {
      const failedImportsArray = this.state.imports_array.filter(i => {
        return arg.data.Result.failed.includes(i.skylink);
      });
      const count = this.state.imports_array.length;
      this.setState({
        import_text: failedImportsArray.length > 0 ? JSON.stringify(failedImportsArray, null, 2) : '',
        imports_array: [],
        second_stage: false,
      }, () => {
        if (failedImportsArray.length > 0) {
          this.props.notifyError(`Failed to import ${failedImportsArray.length} item(s)`);
        } else {
          this.props.notifyInfo('Import Result', `Successfully imported ${count} item(s)`);
        }
      });
    } else {
      this.props.notifyError(arg.data.Error);
    }
  };

  render() {
    return this.props.AppBusy ? (<div/>) : (
      <Box dxDark dxStyle={{
        height: 'auto',
        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.displaySkynetImport(false)}
             style={{cursor: 'pointer'}}>X</a>
        </div>
        <h1
          className={'SkynetImportHeading'}>{this.state.second_stage ? 'Verify Imports' : 'Import List'}</h1>
        {
          this.state.second_stage ? (
            <ImportList imports_array={this.state.imports_array}/>
          ) : (
            <textarea autoFocus={true}
                      className={'SkynetImportTextArea'}
                      onChange={e => this.setState({
                        import_text: e.target.value,
                      })}
                      value={this.state.import_text}
                      rows={10}/>
          )
        }
        <div className={'SkynetImportButtons'}>
          <Button
            buttonStyles={{height: 'auto', marginTop: 'var(--default_spacing)', width: 'auto'}}
            clicked={this.displaySyntax}>Import Syntax...</Button>
          <div className={'SkynetActionButtons'}>
            {
              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 ? 'Import' : 'Next'}</Button>
          </div>
        </div>
      </Box>
    );
  }
});
