import bindAll from 'lodash.bindall';
import React from 'react';
import ReactDOM from 'react-dom';
import PaintEditor from '..';
import {Provider} from 'react-redux';
import {createStore} from 'redux';
import _ from 'lodash';
import queryString from 'query-string';
import reducer from './reducers/combine-reducers';
import {intlInitialState, IntlProvider} from './reducers/intl.js';
import styles from './playground.css';
import RtmClient from '../lib/rtm-client'
import {updateState} from '../reducers/scratch-paint-reducer';
import PaintSyncComponent from '../hocs/paint-sync.jsx'

const appTarget = document.createElement('div');
appTarget.setAttribute('class', styles.playgroundContainer);
document.body.appendChild(appTarget);
const store = createStore(
    reducer,
    intlInitialState,
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
const svgString =
    '<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"' +
            ' x="0px" y="0px" width="32px" height="32px" viewBox="0.5 384.5 32 32"' +
            ' enable-background="new 0.5 384.5 32 32" xml:space="preserve">' +
        '<path fill="none" stroke="#000000" stroke-width="3" stroke-miterlimit="10" d="M7.5,392.241h7.269' +
            'c4.571,0,8.231,5.555,8.231,10.123v7.377"/>' +
        '<polyline points="10.689,399.492 3.193,391.997 10.689,384.5 "/>' +
        '<polyline points="30.185,405.995 22.689,413.491 15.192,405.995 "/>' +
    '</svg>';

const params = queryString.parse(window.location.search)
const {uid, writable} = params
const channelName = '20200520'
console.log('writable', writable);
class Playground extends React.Component {
    constructor (props) {
        super(props);
        bindAll(this, [
            'handleUpdateName',
            'handleUpdateImage',
            'observeStore',
            'deepDiffObj',
            'loginRTM',
            'joinRoom',
            'sendMessage'
        ]);
        // Append ?dir=rtl to URL to get RTL layout
        const match = location.search.match(/dir=([^&]+)/);
        const rtl = match && match[1] == 'rtl';
        this.state = {
            name: 'meow',
            rotationCenterX: 20,
            rotationCenterY: 400,
            imageFormat: 'svg', // 'svg', 'png', or 'jpg'
            image: svgString, // svg string or data URI
            rtl: rtl
        };

        // this.rtm = new RtmClient()

        // console.log('store state : ', store.getState());
    }
    observeStore(store, select, onChange) {
        let currentState = {};

        function handleChange() {
          let nextState = select(store.getState());
          if (nextState !== currentState) {
            const curState = currentState;
            currentState = nextState;
            onChange(curState, nextState);
          }
        }

        let unsubscribe = store.subscribe(handleChange);
        handleChange();
        return unsubscribe;
    }

    deepDiffObj(object, base) {
        if (!object) throw new Error(`The object compared should be an object: ${object}`);
        if (!base) return object;
        const result = _.transform(object, (result, value, key) => {
            if (!_.has(base, key)) result[key] = value; // fix edge case: not defined to explicitly defined as undefined
            if (!_.isEqual(value, base[key])) {
            result[key] = _.isPlainObject(value) && _.isPlainObject(base[key]) ? this.deepDiffObj(base[key], value) : value;
            }
        });
        // map removed fields to undefined
        _.forOwn(base, (value, key) => {
            if (!_.has(object, key)) result[key] = undefined;
        });
        return result;
    }
    loginRTM() {
        try {
            // https://www.agora.io/en/ register
            RtmClient.init('appid')
            RtmClient.login(uid, null).then(() => {
              console.log('login')
              RtmClient._logined = true
              this.joinRoom()
            }).catch((err) => {
              console.error(err)
            })
          } catch (err) {
            console.error(err)
          }
    }
    joinRoom() {

        RtmClient.joinChannel(channelName).then(() => {
          RtmClient.channels[channelName].joined = true
        }).catch((err) => {
          console.error(err)
        })
    }
    sendMessage(message) {
        if (RtmClient.channels[channelName] && !RtmClient.channels[channelName].joined) return
        RtmClient.sendChannelMessage(message, channelName).then(() => {
            console.log('sendChannelMessage : ', message)
        }).catch((err) => {
          console.error(err)
        })
    }
    componentDidMount () {
        // RtmClient.on('ChannelMessage', ({ channelName, args }) => {
        //     const [message, memberId] = args
        //     if (memberId !== uid) {
        //         console.log('channel ', channelName, ', messsage: ', message.text, ', memberId: ', memberId)
        //         if (message.text && message.text.length > 0 && message.text !== '{}') {
        //             // store.state = _.merge(store.state, JSON.parse(message.text))
        //             store.dispatch(updateState(message.text))
        //         }
        //     }
        //   })
        //
        // this.loginRTM()
        // if (writable) {
        //     this.observeStore(store, (state) => {
        //         // console.log('nextState', state)
        //         return state.scratchPaint;
        //     }, (curState, nextState) => {
        //         const dif = this.deepDiffObj(nextState, curState);
        //         // console.log('Changed State', dif, curState, nextState);
        //         if (!_.isEmpty(dif)) {
        //             this.sendMessage(JSON. stringify(dif))
        //         }
        //     })
        // }
    }
    handleUpdateName (name) {
        this.setState({name});
    }
    handleUpdateImage (isVector, image, rotationCenterX, rotationCenterY) {
        // console.log(image);
        // console.log(`rotationCenterX: ${rotationCenterX}    rotationCenterY: ${rotationCenterY}`);
        if (isVector) {
            this.setState({image, rotationCenterX, rotationCenterY});
        } else { // is Bitmap
            // image parameter has type ImageData
            // paint editor takes dataURI as input
            const canvas = document.createElement('canvas');
            const context = canvas.getContext('2d');
            context.putImageData(image, 0, 0);
            this.setState({
                image: canvas.toDataURL('image/png'),
                rotationCenterX: rotationCenterX,
                rotationCenterY: rotationCenterY
            });
        }
    }
    render () {
        return (
            <div>
            <PaintEditor
                {...this.state}
                imageId="meow"
                onUpdateName={this.handleUpdateName}
                onUpdateImage={this.handleUpdateImage}
            />
            <PaintSyncComponent />
            </div>
        );
    }

}
ReactDOM.render((
    <Provider store={store}>
        <IntlProvider>
            <Playground />
        </IntlProvider>
    </Provider>
), appTarget);
