from flask import Flask
from flask_socketio import SocketIO, emit, join_room
from flask import Flask, render_template, session, request
from api.api_request import API
from collections import defaultdict
import logging
import datetime
import json
import sys
import os
import pymongo
# import redis



app = Flask(__name__, template_folder='template')
app.debug = True
app.config['SECRET_KEY'] = 'nuttertools'
socketio = SocketIO(app, cors_allowed_origins="*")
conn = pymongo.MongoClient(host="103.175.220.219", port=27018, username="root", password="3M=Mp(o1JsyfCb6W")
db = conn.socketDB 
userCol = db.users
now = datetime.datetime.now()
api = API()
users = defaultdict(list)


@app.route('/')
def chat():
	return render_template('index.html')


@socketio.on('test')
def test(test):
	app.logger.debug(test)

@socketio.on('typing')
def receive_typing(data):
	# app.logger.debug('receive_typing')
	# app.logger.debug(data)
	emit('incoming_typing',data,room=data['room_id'])

@socketio.on('stoptyping')
def receive_stop_typing(data):
	# app.logger.debug('receive_stop_typing')
	# app.logger.debug(data)
	emit('incoming_stop_typing',data,room=data['room_id'])

@socketio.on('start_broadcast')
def test_broadcast(data):
	app.logger.debug('emit to broadcast_message')
	# app.logger.debug('****************** SID********************')
	# app.logger.debug(data)
	uid = int(data['target_id'])
	try:
		datafind = userCol.find_one({"_id": uid})
		app.logger.debug('****************** SID Found ********************')
		app.logger.debug(data)
		app.logger.debug(datafind['uid'])
		emit('broadcast_message',data,room=datafind['uid'])
		app.logger.debug('****************** SID End ********************')
	except:
		app.logger.debug('SID NOT FOUND WHEN INVITE OR CREATE ROOM')
	# r_data = client.smembers('sid_'+data['id_teknisi'])
	# if len(r_data) > 0:
	# 	app.logger.debug(r_data)
	# 	app.logger.debug(data)
	# 	app.logger.debug(list(r_data)[0])
	# 	emit('broadcast_message',data,room=list(r_data)[0].decode("utf-8"))
	# else:
	# 	app.logger.debug(r_data)
	# 	app.logger.debug(data)
	# 	app.logger.debug('Teknisi ID Not Found')


# Start Connected
@socketio.on('start_connect')
def on_start_room(data):
	try:
		uid = int(data['id'])
		udata = { "_id": uid, "uid": request.sid}
		datafind = userCol.find_one({"_id": uid})
		if datafind:
			new_values = { "$set": { "uid": request.sid } }
			userCol.update_one(datafind, new_values)
		else:
			userCol.insert_one(udata)
		# emit('test_on',data,room=request.sid)
		app.logger.debug( str(uid) +' Connection Established ' + str(request.sid))
	except:
		pass

# Enter Available Room
@socketio.on('join_room')
def on_join_room(data):
	room = data['room_id']
	author = data['author_id']
	if author != 123456:
		app.logger.debug('receive join data with room ' + str(room) + ' author ' +str(author)) 
	join_room(str(room))
	

@socketio.on('enter_room')
def on_enter_room(data):
	app.logger.debug(data)
	room = data['room_id']
	# target_id = data['target_id']
	author_id = data['author_id']
	datafind = userCol.find_one({"_id": int(author_id)})
	if datafind:
		app.logger.debug(datafind)
		new_values = { "$set": { "room_id": str(room) } }
		userCol.update(datafind, new_values)
		emit('update_read',data,room=room)
		post = api.update_read_message(str(room),str(author_id))
		app.logger.debug(post)
		app.logger.debug(author_id +' enter_room ' + 'with SID ' +request.sid)
	else:
		app.logger.debug('not found')

	# emit('update_read',data,room=room)

@socketio.on('exit_room')
def on_exit_room(data):
	room = data['room_id']
	author_id = int(data['author_id'])
	app.logger.debug('exit room ************************************#%@#%@#')
	datafind = userCol.find_one({"_id": author_id})
	if datafind:
		app.logger.debug(datafind)
		new_values = { "$unset": { "room_id": "" } }
		userCol.update(datafind, new_values)
	else:
		app.logger.debug('not found')
	


@socketio.on('change_topic')
def change_topic(data):
	app.logger.debug('change_topic')
	room = data['room_id']
	role = data['role']
	author =data['author_id']
	message = data['message']
	type_mes = data['type']
	post = api.post_message(author,role,room,message,type_mes)
	emit('room_incoming_message',data,room=room)

@socketio.on('room_message')
def room_message(data):
	app.logger.debug(data)
	room = data['room_id']
	author =data['author_id']
	author_name = data['name']
	role = data['role']
	# target_id = data['target_id']
	date = data['date']
	time = data['time']
	kick = data['kick']
	message = data['message']
	type_mes = data['type']
	category = data['category']
	post = api.post_message(author,role,room,message,type_mes)
	app.logger.debug(post)
	# r_data = client.smembers(target_id)
	emit('room_incoming_message',data,room=room)
	# emit('test',data,room=room)
	datafind = userCol.find_one({"room_id": room,"_id": {"$ne" : int(author) }})
	if datafind:
		app.logger.debug('******** ada user di dalam room yang sama ********** ')
		emit('update_read_in_room',data,room=room)
		post = api.update_read_message_in_room(room,author)
		list_member = data['ListMember']
		raw_list = list_member.split(',')
		data_list = list(filter(None, raw_list)) 
		for x in data_list:
			member_id = str(x)
			post_notif= api.send_notif(member_id,room,author_name,message,type_mes,date,time,category)
			app.logger.debug('send_notif to member id : ' + str(x))
			app.logger.debug(post_notif)
	else:
		
		if kick != 'none':
			app.logger.debug('Kick---------------------------Kick')
			kick = data['kick']
			app.logger.debug(kick)
			datafind = userCol.find_one({"_id": int(kick)})
			if datafind is not None and 'uid' in datafind :
				emit('delete_room',data,room=datafind['uid'])
		else:			
			list_member = data['ListMember']
			raw_list = list_member.split(',')
			data_list = list(filter(None, raw_list)) 
			for x in data_list:
				# try:
				member_id = str(x)
				post_notif= api.send_notif(member_id,room,author_name,message,type_mes,date,time,category)
				app.logger.debug('send_notif to member id : ' + str(x))
				app.logger.debug(post_notif)
				datafind = userCol.find_one({"_id": int(x)})
				app.logger.debug('****************** SID Found ********************')
				app.logger.debug(datafind)
				app.logger.debug('****************** SID End   ********************')
				if datafind is not None and 'uid' in datafind :
					emit('new_message_count',data,room=datafind['uid'])
					emit('alert_message',data,room=datafind['uid'])
				
				
				
			
			# except:
			# 	pass
		# if data['kick'] is 'none':
		# 	pass
		# else:
		# 	app.logger.debug('Kick---------------------------Kick')
		# 	kick = data['kick']
		# 	app.logger.debug(kick)
		# 	datafind = userCol.find_one({"_id": int(kick)})
		# 	app.logger.debug(datafind)
		# 	emit('delete_room',data,room=datafind['uid'])
		
		# app.logger.debug('******** Tidak Ada User di dalam room yang sama ********** ')


	# if room.encode("utf-8") in r_data:
	# 	emit('update_read_in_room',data,room=room)
	# 	post = api.update_read_message(room,author)
	# 	app.logger.debug(target_id +' (Target) Sedang Di Dalam Room '+ room)
	# else:
	# 	s_data = client.smembers('sid_'+data['target_id'])
	# 	app.logger.debug(target_id +' (Target) Sedang Di Luar Room ')
	# 	if len(s_data) > 0:
	# 		app.logger.debug(s_data)
	# 		app.logger.debug(list(s_data)[0])
	# 		emit('new_message_count',data,room=list(s_data)[0].decode("utf-8"))
	# 		emit('alert_message',data,room=list(s_data)[0].decode("utf-8"))
	# 	else:
	# 		app.logger.debug(r_data)
	# 		app.logger.debug(data)
	# 		app.logger.debug('Target ID Not Found')
			
@socketio.on('connect')
def connect():
	# app.logger.debug(request.args.get('id'))
	app.logger.debug('Made Connection ' + str(request.sid))
	emit('on_connect','You Connected', broadcast=True)
	# app.logger.debug('Made Connection ' + str(request.sid))

@socketio.on('disconnect')
def test_disconnect():
	app.logger.debug(str(request.sid) + ' Disconnected')
	# datafind = userCol.find_one({"uid": request.sid})
	# userCol.delete_one(datafind)
	datafind = userCol.find_one({"uid": request.sid})
	if datafind:
		app.logger.debug(datafind)
		new_values = { "$unset": { "uid": "","room_id" : ""} }
		userCol.update(datafind, new_values)
	else:
		app.logger.debug('not found')
	
	# r_data = client.smembers(request.sid)
	# client.delete('sid_' +list(r_data)[0].decode("utf-8"))
	# client.delete(list(r_data)[0])
	# client.delete(request.sid)


	# app.logger.debug(str(request.sid) + ' Disconnected')
	# disconnect()

if __name__ == "__main__":
	# app.run(host='0.0.0.0')
    	socketio.run(app, host='0.0.0.0', port=5000)

