/*
 * This file is part of OsmInEdit, released under ISC license (see LICENSE.md)
 *
 * Copyright (c) Adrien Pavie 2019
 * Copyright (c) Daimler AG 2019
 *
 * Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

import React from 'react';
import ReactDOM from 'react-dom';
import Body from './view/Body';
import I18n from './config/locales/ui';
import ImageryManager from './ctrl/ImageryManager';
import AccountAuth from './model/AccountAuth';
import PresetsManager from './ctrl/PresetsManager';
import PubSub from 'pubsub-js';
import request from 'request-promise-native';
import VectorDataManager from './ctrl/VectorDataManager';
// import LocationCard from './view/common/LocationCard';

/**
 * App is the application starter.
 * It creates mostly everything.
 */
class App {
	constructor() {
		this._initI18n();
		this._initCtrl();
		this._initView();
		this._initAuth();
	}

	/**
	 * Initializes internationalization system
	 * @private
	 */
	_initI18n() {
		let locale = null;
		if(window.navigator.languages) {
			for(const l of window.navigator.languages) {
				if(I18n.supportedLocales.includes(l)) {
					locale = l;
					break;
				}
			}
		}

		I18n.changeLocale(locale || window.navigator.userLanguage || window.navigator.language);
	}

	/**
	 * Creates controller objects.
	 * @private
	 */
	_initCtrl() {
		window.vectorDataManager = new VectorDataManager();
		window.presetsManager = new PresetsManager();
		window.imageryManager = new ImageryManager();

		// Preload some data
		window.presetsManager.loadPresets();
		window.imageryManager.getAvailableImagery();
	}

	/**
	 * Create view components
	 * @private
	 */
	_initView() {
		ReactDOM.render(<Body />, document.getElementById('root'));
		document.title=window.EDITOR_NAME;

		// Disabling context menu
		document.oncontextmenu = () => {
			return false;
		};
	}

	/**
	 * Launches authentication process
	 * @private
	 */
	_initAuth() {
		// const opts = {
		// 	apiUrl: window.CONFIG.osm_api_url,
		// 	url: window.CONFIG.osm_api_url,
		// 	client_id: window.CONFIG.oauth_consumer_key,
		// 	redirect_uri: window.EDITOR_URL,
		// 	scope: "read_prefs write_api",
		// 	singlepage: true
		// };

		// window.editor_user_auth = osmAuth(opts);

		// const params = this._readURLParams(window.location.href);

		// if(params.code) {
		// 	window.editor_user_auth.authenticate(() => {
		// 		this._checkAuth();
		// 		localStorage.setItem("oauth_token", params.code);
		// 		window.history.replaceState({}, "", window.location.href.replace(/\?.*/, ""));
		// 	});
		// }
		// else if(localStorage.getItem("oauth_token")) {
		// 	window.editor_user_auth.bootstrapToken(localStorage.getItem("oauth_token"), () => {
		// 		this._checkAuth();
		// 	});
		// }
		// else {
		// 	//Check if we receive auth token
		// 	this._checkAuth();
		// 	this.authWait = setInterval(this._checkAuth.bind(this), 100);
		// }

		window.editor_user_auth = new AccountAuth();

		/**
		 * Event for logging in user
		 * @event app.user.login
		 * @memberof App
		 */
		PubSub.subscribe("app.user.login", (msg, data) => {
			// if(!window.editor_user_auth.authenticated()) {
			// 	window.editor_user_auth.authenticate((err, res) => {
			// 		if(err) {
			// 			console.error(err);
			// 			alert(I18n.t("Oops ! Something went wrong when trying to log you in"));
			// 			PubSub.publish("app.user.logout");
			// 		}
			// 		else {
			// 			this._checkAuth();
			// 		}
			// 	});
			// }
			console.log("index ", data);
			if(!window.editor_user_auth.authenticated()) {
				window.editor_user_auth.authenticate(data, (err, res) => {
					console.log('index ok');
					if(err) {
						console.error(err);
						alert("哎呀！尝试登录时出错。");
						PubSub.publish("app.user.logout");
					}
					else {
						console.log('enter _checkAuth');
						this._checkAuth(res);
					}
				});
			}

		});

		/**
		 * Event for logging out user (not done yet)
		 * @event app.user.logout
		 * @memberof App
		 */
		PubSub.subscribe("app.user.logout", (msg, data) => {
			if(window.editor_user_auth && window.editor_user_auth.authenticated()) {
				window.editor_user_auth.logout();
			}

			window.editor_user = null;
			localStorage.removeItem("oauth_token");

			/**
			 * Event when user has been successfully logged out
			 * @event app.user.left
			 * @memberof App
			 */
			PubSub.publish("app.user.left");
		});

		PubSub.subscribe('body.data.save', (msg, data) => {
			window.editor_user_auth.updateMapData({
				map_data: data,
				user_id: window.editor_user.id,
				map_id: window.editor_user.edit_map,
			});
		});
		
		PubSub.subscribe('body.data.autosave', (msg, data) => {
			window.editor_user_auth.updateMapDataDontGet({
				map_data: data,
				user_id: window.editor_user.id,
				map_id: window.editor_user.edit_map,
			});
		});

		PubSub.subscribe('editor.map.create', (msg, data) => {
			window.editor_user_auth.cteateMapData(data.id, data.name);
		});

		PubSub.subscribe('editor.map.rename', (msg, data) => {
			window.editor_user_auth.updateMapName(data.id, data.name);
		});

		PubSub.subscribe('editor.map.edit', (msg, data) => {
			// window.editor_user_auth.cteateMapData(data.id, data.name);
			const map = window.editor_user.maps.filter(m => m.map_id === data.id)[0];
			window.editor_user.edit_map = data.id;
			PubSub.publish('body.map.change', map);
		});

		PubSub.subscribe('editor.map.delete', (msg, data) => {
			window.editor_user_auth.deleteMapData(data.id);
		});
	}

	/**
	 * Check if authentication happened
	 * @private
	 */
	_checkAuth(res) {
		if(window.editor_user_auth.authenticated()) {
			if(this.authWait) {
				clearInterval(this.authWait);
			}

			try {
				window.editor_user = {
					id: res.user_id,
					account: res.user_account,
					token: res.user_token,
					name: res.user_name,
					auth: window.editor_user_auth,
					edit_map: 0,
					maps: []
				};

				// console.log('_checkAuth', window.editor_user);

				//登录完成后查询是否有地图数据，如没有则创建一个
				window.editor_user_auth.hasMapData(res.user_id);

				/**
				 * Event when user has been successfully logged in
				 * @event app.user.ready
				 * @memberof App
				 */
				PubSub.publish("app.user.ready", { username: window.editor_user.name });
				console.log("Logged in as", window.editor_user.name);

				localStorage.setItem("user_token", res.user_token);
			}
			catch(e) {
				console.error(e);
				PubSub.publish("app.user.logout");
			}

			//Get user details
			// window.editor_user_auth.xhr({
			// 	method: 'GET',
			// 	path: '/api/0.6/user/details'
			// }, (err, details) => {
			// 	if(err) {
			// 		console.log(err);
			// 		window.editor_user_auth.logout();
			// 	}
			// 	else {
			// 		try {
			// 			window.editor_user = {
			// 				id: details.firstChild.childNodes[1].attributes.id.value,
			// 				name: details.firstChild.childNodes[1].attributes.display_name.value,
			// 				auth: window.editor_user_auth
			// 			};

			// 			/**
			// 			 * Event when user has been successfully logged in
			// 			 * @event app.user.ready
			// 			 * @memberof App
			// 			 */
			// 			PubSub.publish("app.user.ready", { username: window.editor_user.name });
			// 			console.log("Logged in as", window.editor_user.name);
			// 		}
			// 		catch(e) {
			// 			console.error(e);
			// 			PubSub.publish("app.user.logout");
			// 		}
			// 	}
			// });
		}
	}

	/**
	 * Parse URL parameters
	 * @private
	 */
	_readURLParams(str) {
		const u = str.split('?');

		if(u.length > 1) {
			const p = u[1].split('#')[0];

			return p.split('&').filter(function (pair) {
				return pair !== '';
			}).reduce(function(obj, pair){
				var parts = pair.split('=');
				obj[decodeURIComponent(parts[0])] = (null === parts[1]) ?
					'' : decodeURIComponent(parts[1]);
				return obj;
			}, {});
		}
		else {
			return {};
		}
	}
}


/*
 * Global variables definition
 */

window.EDITOR_URL = window.location.origin + window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + "/";
window.UNUSABLE_ICONS = new Set();

// Dynamically load config file
request(window.EDITOR_URL + "/config.json")
.then(configTxt => {
	window.CONFIG = JSON.parse(configTxt);
	window.EDITOR_NAME = window.CONFIG.editor_name;

	// Create app
	new App();	
})
.catch(e => {
	console.error(e);
	alert("Can't load configuration file, please report this issue.");
});
// let datas = []
// setTimeout(() => {
// 	let sock = new WebSocket("ws://127.0.0.1:9002");
// 	sock.onmessage = (msg) => {
// 		// console.log(msg.data);
// 		manageData(msg.data);
// 	}
// }, 1000);

// function manageData(data){
// 	let dat = JSON.parse(data).data;
// 	// datas.forEach(d => {
// 	// 	if(d[3]){
// 	// 		console.log(d[1],new Date( d[3]), datas.length);
// 	// 	}
// 	// });

// 	let card = new LocationCard(39.96348, 116.36831 + dat[2] * 0.00001141, dat[0], dat[3], dat[1],  
// 		<span>{dat[2]}</span>
// 	); 
// 	if(datas.length === 0){
// 		datas.push(card);
// 	}
// 	if(!datas.some(t => t.card === dat[1])){
// 		datas.push(card);
// 	} else {
// 		datas = datas.map(t => {
// 			if(t.card === dat[1]) {
// 				return card;
// 			} else {
// 				return t;
// 			}
// 		});
// 	}
// 	PubSub.publish('body.data.got', datas);
// }