import * as path from 'path';
import {ipcRenderer, remote} from 'electron';
import * as R from 'ramda';
import React from 'react';
import lodash from 'lodash';
import {withRouter} from 'next/router';
import qs from 'query-string';
import got from 'got';
import ChevronsRight from '../icons/ChevronsRight';
import {throttle} from 'throttle-debounce';
export default class Index extends React.Component {
  activeShortcutKeys = [];
  scrollable = null;

  constructor(props) {
    super(props);

    if (typeof window === 'undefined') {
      this.state = {
        selectedFile: null,
        files: [],
        filename: '',
        originOpacity: 1,
        opacity: 1
      };

      return;
    }

    const query = qs.parse(location.search);

    this.state = {
      ...query,
      selectedFile: null,
      files: [],
      originOpacity: 1,
      opacity: 1
    };
  }

  lockScroll = () => {
    if (this.scrollable === null) {
      return;
    }

    this.scrollable.style.overflow = 'hidden';
  };

  unlockScroll = () => {
    if (this.scrollable === null) {
      return;
    }

    this.scrollable.style.overflow = 'auto';
  };

  selectFile = file => async () => {
    this.setState({
      selectedFile: file
    });
    const window = remote.getCurrentWindow();
    window.setIgnoreMouseEvents(true);

    setTimeout(async () => {
      await this.maybeResizeWindow();
      await got.post(
        `http://localhost:33322/api/v1/selected-file?filename=${file.filename}`
      );
    }, 0);
  };

  resetFile = async () => {
    this.setState({
      selectedFile: null
    });
    const window = remote.getCurrentWindow();
    window.setSize(500, 500, false);
    window.setIgnoreMouseEvents(false);

    await got.delete(`http://localhost:33322/api/v1/selected-file`);
  };

  render() {
    if (this.state.selectedFile === null) {
      return (
        <>
          <style jsx="true">{`
            .menu {
              height: 37px;
              background: #eee;
              border-bottom: 1px solid rgba(0, 0, 0, 0.1);
              display: flex;
              justify-content: center;
              font-family: Menlo;
              font-size: 12px;
              color: #888;
              align-items: center;
            }

            .box {
              display: flex;
              flex-wrap: wrap;
              background: #eee;
              max-height: 360px;
              width: 100vw;
              overflow: auto;
              border-bottom-left-radius: 8px;
              border-bottom-right-radius: 8px;
              padding-bottom: 10px;
            }

            .item {
              flex: 1;
              flex-basis: 30vw;
              max-height: 30vh;
              max-width: 232px;
              margin: 0.5em;
              display: flex;
              flex-direction: column;
              border: 1px solid rgba(0, 0, 0, 0.1);
              background: #fff;
            }

            .image-wrapper {
              flex: 1 1 30vw;
              overflow: auto;
            }

            .image {
              max-width: 100%;
            }

            .controll {
              font-size: 12px;
              border-top: 1px solid rgba(0, 0, 0, 0.1);
              display: flex;
            }

            .filename {
              flex: 1;
              padding: 0.5em;
              overflow: auto;
              white-space: pre;
            }

            .icon-wrapper {
              display: flex;
              justify-content: center;
              align-items: center;
              cursor: pointer;
              padding: 0.5em;
              padding-left: 0.7em;
              transition: 0.2s;
              height: 100%;
              box-sizing: border-box;
              background: rgba(0, 0, 0, 0.2);
              // border-left: 1px dotted #2d260b;
            }

            .icon-wrapper:hover,
            .icon-wrapper:active {
              background: #ffd105;
              // border-left-style: solid;
            }

            .action-group {
              flex: 0;
            }
          `}</style>

          <div
            className="menu"
            style={{
              WebkitAppRegion: 'drag'
            }}
          >
            Zuru
          </div>
          <div
            className="box"
            ref={div => {
              this.scrollable = div;
            }}
          >
            {this.state.files.map(file => {
              return (
                <div className="item">
                  <div className="image-wrapper">
                    <img
                      className="image"
                      src={`./static${file.filename}`}
                      onMouseEnter={this.lockScroll}
                      onMouseLeave={this.unlockScroll}
                    />
                  </div>
                  <div className="controll">
                    <div className="filename">
                      {path.basename(
                        file.filename,
                        path.extname(file.filename)
                      )}
                    </div>
                    <div className="action-group">
                      <div
                        className="icon-wrapper"
                        onClick={this.selectFile(file)}
                      >
                        <ChevronsRight />
                      </div>
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </>
      );
    }

    // console.log(this.props);
    return (
      <>
        <style jsx="true">{`
          .wrapper {
            position: absolute;
            left: 0;
            top: 0;
            width: 100vw;
            height: 100vh;
            box-sizing: border-box;
            transition: 0.5s;
            border: 2px solid
              ${this.state.opacity === 0.25 ? '#f7d94c' : 'transparent'};
          }

          .view {
            opacity: ${this.state.opacity};
            transition: 0.5s;
            width: 100vw;
            height: 100vh;
            overflow: auto;
          }

          .background {
            background: url(./static${this.state.selectedFile.filename});
            height: ${this.state.selectedFile.dimensions.height}px;
            width: 100vw;
          }
        `}</style>
        <div style={{marginTop: '79px'}}>
          <div
            id="view"
            className="view"
            style={{
              WebkitAppRegion: 'drag'
            }}
          >
            <div className="background" />
          </div>
        </div>
        <div className="wrapper" />
      </>
    );
  }

  resetTransparent = lodash.debounce(() => {
    this.setState({
      opacity: this.state.originOpacity
    });
  }, 2000);

  handleMove = () => {
    this.setState({
      opacity: 0.25
    });

    this.resetTransparent();
    this.maybeResizeWindow();
  };

  getHeight = (height, currentY) => {
    const displayHeight = remote.screen.getPrimaryDisplay().workArea.height;
    if (displayHeight < height) {
      return displayHeight - currentY;
    } else if (displayHeight < height + currentY) {
      const overSize = height + currentY - displaySize.height;
      return height + overSize;
    }

    return height;
  };

  getWindowWidth = () => {
    if (this.state.selectedFile === null) {
      return 500;
    }

    return this.state.selectedFile.dimensions.width;
  };

  getWindowHeight = () => {
    if (this.state.selectedFile === null) {
      return 500;
    }

    const [x, y] = remote.getCurrentWindow().getPosition();
    return this.getHeight(this.state.selectedFile.dimensions.height, y);
  };

  maybeResizeWindow = async () => {
    const currentWindow = remote.getCurrentWindow();
    const width = this.getWindowWidth();
    const height = this.getWindowHeight();

    currentWindow.setContentSize(width, height);
    const [x, y] = currentWindow.getPosition();

    const query = qs.stringify({width, height, x, y});

    await got.post(`http://localhost:33322/api/v1/window?${query}`);

    setTimeout(() => {
      if (this.ws.readyState !== 1) {
        return;
      }

      if (this.state.selectedFile === null) {
        return;
      }
      
      this.ws.send(
        JSON.stringify({
          type: 'MOVE_ZURU_APP',
          windowState: {width, height, x, y}
        })
      );
    }, 0);
  };

  // remote.getCurrentWindow() だと
  // fs関連の問題でエラーになった
  handleShortcut = ev => {
    if (this.state.selectedFile === null) {
      return;
    }

    if (ev.key === 'Shift') {
      if (ev.type === 'keydown') {
        remote.getCurrentWindow().setIgnoreMouseEvents(false);
      } else {
        remote.getCurrentWindow().setIgnoreMouseEvents(true);
      }
    }

    if (ev.key === 'Escape') {
      this.resetFile();
      return;
    }

    if (['3', '4', '5', '6', '7', '8', '9', '0'].indexOf(ev.key) > -1) {
      let val = Number(ev.key) / 10;
      if (ev.key === '0') {
        val = 1;
      }

      this.setState({
        originOpacity: val,
        opacity: val
      });

      return;
    }

    switch (ev.key) {
      case 'k':
      case 'ArrowUp': {
        this.setState({
          opacity: 0.25
        });

        if (ev.type === 'keydown') {
          this.activeShortcutKeys = this.activeShortcutKeys.filter(
            key => key !== 'k' && key !== 'j'
          );
          this.activeShortcutKeys.push('k');
        } else {
          this.activeShortcutKeys = this.activeShortcutKeys.filter(
            key => key !== 'k'
          );
        }

        this.maybeResizeWindow();
        break;
      }
      case 'l':
      case 'ArrowRight': {
        this.setState({
          opacity: 0.25
        });

        if (ev.type === 'keydown') {
          this.activeShortcutKeys = this.activeShortcutKeys.filter(
            key => key !== 'l' && key !== 'h'
          );
          this.activeShortcutKeys.push('l');
        } else {
          this.activeShortcutKeys = this.activeShortcutKeys.filter(
            key => key !== 'l'
          );
        }

        this.maybeResizeWindow();
        break;
      }
      case 'j':
      case 'ArrowDown': {
        this.setState({
          opacity: 0.25
        });

        if (ev.type === 'keydown') {
          this.activeShortcutKeys = this.activeShortcutKeys.filter(
            key => key !== 'j' && key !== 'k'
          );
          this.activeShortcutKeys.push('j');
        } else {
          this.activeShortcutKeys = this.activeShortcutKeys.filter(
            key => key !== 'j'
          );
        }

        this.maybeResizeWindow();
        break;
      }
      case 'h':
      case 'ArrowLeft': {
        this.setState({
          opacity: 0.25
        });

        if (ev.type === 'keydown') {
          this.activeShortcutKeys = this.activeShortcutKeys.filter(
            key => key !== 'h' && key !== 'l'
          );
          this.activeShortcutKeys.push('h');
        } else {
          this.activeShortcutKeys = this.activeShortcutKeys.filter(
            key => key !== 'h'
          );
        }

        this.maybeResizeWindow();
        break;
      }
    }

    ipcRenderer.send('shortcut', JSON.stringify(this.activeShortcutKeys));
  };

  sendScrollPosition = throttle(100, () => {
    if (this.ws.readyState !== 1) {
      return;
    }

    this.ws.send(
      JSON.stringify({
        type: 'SCROLL',
        scrollY: document.getElementById('view').scrollTop
      })
    );
  });

  handleScroll = () => {
    this.sendScrollPosition();
  };

  focusApp = () => {
    setTimeout(() => {
      const win = remote.getCurrentWindow();
      win.focus();
    }, 100);
  };

  scroll = top => {
    document.getElementById('view').scrollTop = top;
  };

  async componentDidMount() {
    const {body: files} = await got('http://localhost:33322/api/v1/files');
    this.setState({files: JSON.parse(files)});

    document.addEventListener('keydown', this.handleShortcut);
    document.addEventListener('keyup', this.handleShortcut);

    ipcRenderer.on('move', this.handleMove);

    this.ws = new WebSocket(`ws://localhost:33322`);
    // this.ws.on('open', () => {
    //   this.changePosition();
    // });
    this.ws.onmessage = ev => {
      const action = JSON.parse(ev.data);
      console.log('action: ', action);

      switch (action.type) {
        case 'SELECT_FILE': {
          this.selectFile(action.file)();
          return;
        }
        case 'UNSELECT_FILE': {
          this.resetFile();
          return;
        }
        case 'FOCUS_ZURU_APP': {
          this.focusApp();
          return;
        }
        case 'CHROME_SCROLL': {
          this.scroll(action.scrollY);
        }
        default:
          return;
      }
    };
  }

  componentDidUpdate(_, prevState) {
    if (prevState.selectedFile === null && this.state.selectedFile !== null) {
      document
        .getElementById('view')
        .addEventListener('scroll', this.handleScroll);
    }
  }

  componentWillUpdate(_, nextState) {
    if (this.state.selectedFile !== null && nextState.selectedFile === null) {
      document
        .getElementById('view')
        .removeEventListener('scroll', this.handleScroll);
    }
  }

  componentWillUnmount() {
    document.removeEventListener('keydown', this.handleShortcut);
    document.removeEventListener('keyup', this.handleShortcut);
    document
      .getElementById('view')
      .removeEventListener('scroll', this.handleScroll);

    ipcRenderer.removeListener('move', this.handleMove);
  }
}

// export default withRouter(Index);
