import './hydration.css';
import {SAMPLE_CODE} from './data';
import {CodeEditor, CodeError} from './Code';
import {compile} from './code-transformer';
import {reactPaths} from '../../../react-loader';
import qs from 'query-string';

const React = window.React;

class Hydration extends React.Component {
  state = {
    error: null,
    code: SAMPLE_CODE,
    hydrate: true,
  };

  ready = false;

  componentDidMount() {
    window.addEventListener('message', this.handleMessage);
  }

  componentWillUnmount() {
    window.removeEventListener('message', this.handleMessage);
  }

  handleMessage = event => {
    var data = JSON.parse(event.data);

    switch (data.type) {
      case 'ready':
        this.ready = true;
        this.injectCode();
        break;
      default:
        throw new Error(
          'Editor Error: Unrecognized message "' + data.type + '"'
        );
    }
  };

  injectCode = () => {
    try {
      this.send({
        type: 'code',
        payload: compile(this.state.code),
      });

      this.setState({error: null});
    } catch (error) {
      this.setState({error});
    }
  };

  send = message => {
    if (this.ready) {
      this.frame.contentWindow.postMessage(JSON.stringify(message), '*');
    }
  };

  setFrame = frame => {
    this.frame = frame;
  };

  setCode = code => {
    this.setState({code}, this.injectCode);
  };

  setCheckbox = event => {
    this.setState({
      [event.target.name]: event.target.checked,
    });
  };

  render() {
    const {code, error, hydrate} = this.state;
    const src = '/renderer.html?' + qs.stringify({hydrate, ...reactPaths()});

    return (
      <div className="hydration">
        <header className="hydration-options">
          <label htmlFor="hydrate">
            <input
              id="hydrate"
              name="hydrate"
              type="checkbox"
              checked={hydrate}
              onChange={this.setCheckbox}
            />
            Auto-Hydrate
          </label>
        </header>

        <CodeEditor code={code} onChange={this.setCode} />

        <CodeError error={error} className="hydration-code-error" />

        <iframe
          ref={this.setFrame}
          className="hydration-sandbox"
          title="Hydration Preview"
          src={src}
        />
      </div>
    );
  }
}

export default Hydration;
