from channels.generic.websocket import WebsocketConsumer
from asgiref.sync import async_to_sync

import time
import json

class ChatNoticeConsumer(WebsocketConsumer):

	def connect(self):

		user = self.scope["user"]
		#if (user.is_anonymous or not user.is_authenticated):
			#return

		if (self.channel_layer == None):
			return

		self.room_group_name = f'chatNotice{user.pk}'
		if (not hasattr(self.channel_layer, "users_channels")):
			self.channel_layer.users_channels = {}
		self.channel_layer.users_channels[user.pk] = self.channel_name

		if (not hasattr(self.channel_layer, "invite")):
			self.channel_layer.invite = {}
		self.channel_layer.invite[user.pk] = [];

		async_to_sync(self.channel_layer.group_add)(
			self.room_group_name,
			self.channel_name
		)

		self.accept()

		message_time: int = int(time.time() * 1000)
		targets = list(self.channel_layer.users_channels.keys())
		for target in targets:
			channel = self.channel_layer.users_channels.get(target)
			if (channel == None or target == user.pk):
				continue
			async_to_sync(self.channel_layer.send)(channel, {
				'type':"online_users",
				'author_id':user.pk,
				'targets': targets,
				'time':message_time,
				'status': 200,
			})

	def disconnect(self, code):

		user = self.scope["user"]
		if (user.is_anonymous or not user.is_authenticated):
			return	

		self.channel_layer.users_channels.pop(user.pk)

		message_time: int = int(time.time() * 1000)

		targets = list(self.channel_layer.users_channels.keys())
		for target in targets:
			channel = self.channel_layer.users_channels.get(target)
			if (channel == None or target == user.pk):
				continue
			async_to_sync(self.channel_layer.send)(channel, {
				'type':"online_users",
				'author_id':user.pk,
				'targets': targets,
				'time':message_time,
				'status': 200,
			})

	def receive(self, text_data=None, bytes_data=None):

		if text_data == None:
			return

		user = self.scope["user"]
		#if (user.is_anonymous or not user.is_authenticated):
			#return

		text_data_json = json.loads(text_data)
		
		type_notice = text_data_json.get('type')
		targets : list = text_data_json.get('targets')
		content : dict = text_data_json.get('content')

		if (type_notice == None or targets == None):
			return

		if (self.channel_layer == None):
			return

		message_time: int = int(time.time() * 1000)
		status = 200;

		#print("receive" + str(user.pk))

		try:
			status = getattr(self, "pre_" + type_notice)(user, targets)
		except AttributeError:
			print(f"La fonction pre_{type_notice} n'existe pas.")

		if targets == "all":
			targets = list(self.channel_layer.users_channels.keys())

		for target in targets:
			channel = self.channel_layer.users_channels.get(target)
			if (channel == None or target == user.pk):
				if (channel == None):
					status = 404
				continue
			async_to_sync(self.channel_layer.send)(channel, {
				'type':type_notice,
				'author_id':user.pk,
				'content':content,
				'targets': targets,
				'time':message_time,
				'status': 200,
			})
		async_to_sync(self.channel_layer.send)(self.channel_layer.users_channels.get(user.pk), {
			'type':type_notice,
			'author_id':user.pk,
			'content':"notice return",
			'targets': targets,
			'time':message_time,
			'status':status,
		})


	def pre_invite(self, user, targets):
		status = 200

		for target in targets:
			if (target in self.channel_layer.invite[user.pk]):
				status = 409
		return status

	def invite(self, event):

		user = self.scope["user"]
		if (user.is_anonymous or not user.is_authenticated):
			return

		if (user.pk in self.channel_layer.invite[event["author_id"]]):
			return

		if (user.pk != event["author_id"]):
			self.channel_layer.invite[event["author_id"]].append(user.pk)

		self.send(text_data=json.dumps({
			'type':event['type'],
			'author_id':event['author_id'],
			'content':event['content'],
			'targets': event['targets'],
			'time': event['time'],
			'status':event['status'],
		}))

	def pre_online_users(self, user, targets):
		pass

	def online_users(self, event):

		user = self.scope["user"]
		#if (user.is_anonymous or not user.is_authenticated):
			#return

		#print("online_users" + str(user.pk))

		event['content'] = self.channel_layer.users_channels

		self.send(text_data=json.dumps({
			'type':event['type'],
			'author_id':event['author_id'],
			'content':event['content'],
			'time': event['time'],
			'status':event['status'],
		}))
