import { navigateTo } from "../../index.js";
import {createNotification} from "../../utils/noticeUtils.js";

class Notice {
	constructor(client) {
		this.client = client;
		this.data = {};

		// users online, invited by ..., asked by ..., asker to ...
		let data_variable = ["online", "invited", "asked", "asker"];
		for (let i in data_variable)
			this.data[data_variable[i]] = [];

		//this.connect();

	}

	async connect() {
		return
		let url = `${window.location.protocol[4] === 's' ? 'wss' : 'ws'}://${window.location.host}/ws/chat/notice`;

		this.chatSocket = new WebSocket(url);
		this.chatSocket.onmessage = (event) =>{
			let send = JSON.parse(event.data);
			//console.log("notice: ", send);

			try {
				this["receive_" + send.type](send);
			} 
			catch (error) {
				console.log("receive_" + send.type + ": Function not found");
			}

		};
	    this.chatSocket.onopen = (event) => {
			this.getOnlineUser();
			this.ask_friend();
		};
	}

	async disconnect() {
		if (this.chatSocket == undefined)
			return ;

		this.chatSocket.close();
	}

	async reconnect() {
		this.disconnect();
		this.connect();
	}

	async accept_invite(invitedBy) {

		this.sendRequest({
			type: "accept_invite",
			targets: [invitedBy],
		});

	}

	async receive_accept_invite(send) {

		this.data.invited = send.invites;
		let id_game = send.id_game;
		navigateTo("/game/" + id_game);

	}

	async refuse_invite(invitedBy) {

		this.sendRequest({
			type: "refuse_invite",
			targets: [invitedBy],
		});


	}
	async receive_refuse_invite(send) {

		this.data.invited = send.invites;

		if (send.author_id == this.client.me.id) {
			if (this.rewrite_invite !== undefined)
				this.rewrite_invite();
		}
		else {
			let sender = await this.client.profiles.getProfileId(send.author_id);
			createNotification(sender.username + " refuse your invitation");
		}

	}


	async send_invite(id_inviteds) {

		this.sendRequest({
			type: "invite",
			targets: id_inviteds,
			time: new Date().getTime(),
		});

	}

	async receive_invite(send) {
		
		if (this.client.me == undefined)
			return ;

		let content = send.invites;

		if (send.author_id == this.client.me.id) {
			if (send.status == 200) {
				for (let target in send.targets)
				return createNotification("Invitation send");
			}
			else if (send.status == 444)
				return createNotification("User not connected");
			else if (send.status == 409)
				return createNotification("Already invited");
		}
		else {

			// Regarder qu'il est bien invité par l'auteur
			// Et qu'il n'est pas déjà invité
			if (!content.includes(send.author_id) || 
				this.data.invited.includes(send.author_id))
				return;

			this.data.invited = content;
			let sender = await this.client.profiles.getProfileId(send.author_id);

			createNotification("Invitation received by " + sender.username);

			if (this.rewrite_invite !== undefined)
				this.rewrite_invite();
		}
	}

	async getOnlineUser() {
		
		this.online_users = {};

		this.sendRequest({
			type: "online_users",
			targets: [],
			time: new Date().getTime(),
		});

	}

	async receive_online_users(send) {
		let content = send.online;
		if (content !== undefined) {

			if (this.data.online.length > 0) {
				// get all disconnect user
				//let disconnects = this.data["online"].filter(id => !Object.keys(content).includes(id));
				
				let disconnects = [];

				for (const [key, value] of Object.entries(this.data.online)) {
					if (content[key] == "red" && value == "green")
						disconnects.push(key);
				}

				// delete invite
				this.data.invited = this.data.invited.filter(id => !disconnects.includes(id));

				//console.log(this.data["invited"]);
			}

			this.data.online = content;

			if (this.rewrite_usernames !== undefined)
				this.rewrite_usernames();
		}
	}

	async ask_friend(user_id=undefined) {
		this.sendRequest({
			type: "ask_friend",
			targets: [user_id],
			time: new Date().getTime(),
		});
	}

	async receive_ask_friend(send) {

		let my_id = (this.client.me && this.client.me.id) || send.author_id;
		if (send.author_id == my_id) {
			if (send.status == 400)
				createNotification("Friend ask error");
			else if (send.status == 409)
				createNotification("Already asked friend");
		}

		//if (!send.asked.includes(send.author_id) || 
			//this.data["asked"].includes(send.author_id))
			//return;

		//if (!send.asker.includes(send.author_id) || 
			//this.data["asker"].includes(send.author_id))
			//return;

		this.data.asked = send.asked;
		this.data.asker = send.asker;

		if (send.author_id != my_id) {
			let sender = await this.client.profiles.getProfileId(send.author_id);
			if (this.data.asker.includes(send.author_id))
				createNotification(sender.username + " ask you as friend");
			if (this.rewrite_profile !== undefined)
				await this.rewrite_profile();
		}
		
	}

	async remove_friend(user_id) {
		this.sendRequest({
			type: "remove_friend",
			targets: [user_id],
			time: new Date().getTime(),
		});
	}

	async receive_remove_friend(send) {

		if (send.author_id == this.client.me.id) {
			if (send.status == 400)
				createNotification("Error remove Friend");
			else if (send.status == 409)
				createNotification("Not friend, wtf");

		}

		if (this.rewrite_profile !== undefined)
			await this.rewrite_profile();

		this.receive_online_users(send);
	}

	async accept_friend(user_id) {
		this.sendRequest({
			type: "accept_friend",
			targets: [user_id],
			time: new Date().getTime(),
		});
	}

	async receive_accept_friend(send) {
		this.data.asked = send.asked;
		this.data.asker = send.asker;
		let sender = await this.client.profiles.getProfileId(send.author_id);

		if (send.author_id == this.client.me.id) {
			if (send.status == 400)
				createNotification("Error accept Friend");
			else if  (send.status == 404)
				createNotification("Not found request Friend");
			else if (send.status == 409)
				createNotification("Already Friend, wtf");
		}
		else {
			createNotification(sender.username + " accept your friend request");
		}

		if (this.rewrite_profile !== undefined)
			await this.rewrite_profile();

		this.receive_online_users(send);
	}

	async refuse_friend(user_id) {
		this.sendRequest({
			type: "refuse_friend",
			targets: [user_id],
			time: new Date().getTime(),
		});
	}

	async receive_refuse_friend(send) {
		this.data.asked = send.asked;
		this.data.asker = send.asker;
		let sender = await this.client.profiles.getProfileId(send.author_id);

		if (send.author_id == this.client.me.id) {
			if (send.status == 400)
				createNotification("Error refuse Friend");
			else if  (send.status == 404)
				createNotification("Not found request Friend");
			else if (send.status == 409)
				createNotification("Already Friend, WTF");

		}
		if (this.rewrite_profile !== undefined)
			await this.rewrite_profile();
	}

	async sendRequest(content) {
		if (this.chatSocket == undefined)
			return;

		this.chatSocket.send(JSON.stringify(content));
	}
}

export {Notice};
