// Copyright 2020 Thomas Hintz
//
// This file is part of the Alpha Centauri Farming project.
//
// The Alpha Centauri Farming project is free software: you can
// redistribute it and/or modify it under the terms of the GNU General
// Public License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// The Alpha Centauri Farming project is distributed in the hope that
// it will be useful, but WITHOUT ANY WARRANTY; without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE.  See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with the Alpha Centauri Farming project.  If not, see
// <https://www.gnu.org/licenses/>.

require('./style.scss');

import React, { Fragment } from 'react'
import ReactDOM from 'react-dom'
import { Provider, connect } from 'react-redux'

import * as Ws from './websocket.js'
import { rootId } from './constants.js'

import App from './components/app/App.jsx'
import { initialize, handleMessage as handleMessageFarm } from './components/farm/interface.js'

import { setStartGames, startOrJoinGame, setUser, setOpenGames,
         setErrors } from './components/start/actions.js'
import { play } from './components/app/actions.js'
import { createStore } from 'redux'
import rootReducer from './rootReducers.js'

const store = createStore(rootReducer);
const unsubscribe = store.subscribe(() => console.log(store.getState()));

function makeDiv(id) {
    const element = document.createElement('div');
    element.id = id;
    return element;
}

document.body.appendChild(makeDiv(rootId));

window.store = store;

const createAccount = (msg) => {
    Ws.sendCommand({ type: 'create-account', ...msg});
}

const login = (msg) => {
    Ws.sendCommand({ type: 'login', ...msg});
}

const logout = () => {
    Ws.sendCommand({ type: 'logout'});
}

ReactDOM.render(
    <Provider store={store}>
        <App createAccount={createAccount}
             login={login}
             logout={logout}
        />
    </Provider>,
    document.getElementById(rootId)
);

const unsubscribeNewOrJoinGame = store.subscribe(() => {
    const state = store.getState();
    if (state.start.msg) {
        unsubscribeNewOrJoinGame();
        Ws.sendCommand(state.start.msg);
    }
});

let autostart = new URL(window.location.href).searchParams.get('autostart');
let rejoin = new URL(window.location.href).searchParams.get('reload-game');

function handleMessage(evt) {
    const data = JSON.parse(evt.data),
          type = data.event;

    if (data.event === 'error') {
        console.log('error:' + data.exn);
    } else if (data.event === 'new-game-started') {
        history.replaceState({}, document.title, '/');
        console.log('clearing auto-reload');
        initialize(store, Ws.sendCommand);
        Ws.setMainOnMessage(handleMessageFarm);
        Ws.openSecondary('push-web-socket');
        Ws.setSecondaryOnMessage(handleMessageFarm);
        Ws.sendCommand({ type: 'init' })
        store.dispatch(play());
    } else if (data.event === 'start-init') {
        store.dispatch(setStartGames(data.games.games));
        store.dispatch(setOpenGames(data.openGames.games));
        store.dispatch(setUser(data.user));
        store.dispatch(setErrors(data.errors));
        if (autostart) {
            if (data.games.games.length === 0) {
                store.dispatch(startOrJoinGame({ type: 'new-game',
                                                 playerName: 'a',
                                                 checkedColor: 'green',
                                                 gameName: 'a' }));
            } else {
                store.dispatch(startOrJoinGame({ type: 'join-game',
                                                 playerName: 'Player ' + data.games.games[0].colors[0],
                                                 checkedColor: data.games.games[0].colors[0],
                                                 gameId: data.games.games[0].id,
                                                 gameName: data.games.games[0].name }));
            }
        }
        if (rejoin) {
            store.dispatch(startOrJoinGame({ type: 'join-as-existing',
                                             gameId: false }));
        }
    }
}

Ws.openMain('web-socket');
Ws.setMainOnMessage(handleMessage);
Ws.setMainOnOpen(() => Ws.sendCommand({ type: 'main-init' }));
