from flask import Flask, render_template, request
from flask_socketio import SocketIO, send, emit, join_room, leave_room, \
close_room, disconnect

APP = Flask(__name__)
APP.config['SECRET_KEY'] = 'AFixedStudyingSecretKeyThatShouldntBeUsed'
APP.config['DEBUG'] = True

SOCKETIO = SocketIO(APP)

USERS = dict()


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


@APP.route('/server_generated_msg')
def server_generated_msg():
    # Will send to everyone connected because there's no way for the server to
    # pick a specific client.
    SOCKETIO.emit('server generated msg', 'Message generated by event in the server')
    return f"<h1>Event generated in the server</h1>"


@SOCKETIO.on('message from user', namespace='/messages')
def receive_message_from_user(message):
    print(f'Message received from client using JQuery: {message} - session id:' \
          f' {request.sid}')
    #emit('from flask', f'You said {message}')
    emit('from flask', f'Broadcast to all connected to the server: {message}',
         broadcast=True, namespace='/')


@SOCKETIO.on('message')
def receive_message(message):
    print(f'----->Message received from the client: {message}')
    send('This is a message sent from the Flask server')


@SOCKETIO.on('custom event')
def receive_custom_event(obj):
    print(f'----->Name received by the client: {obj["name"]}')
    emit('from flask', {'nickname': 'Pedra Pequena'}, json=True)


@SOCKETIO.on('username', namespace='/private')
def receive_username(username):
    USERS[username] = request.sid
    print(f'Users: {USERS}')


@SOCKETIO.on('private_message', namespace='/private')
def receive_private_message(obj):
    recipient_session_id = USERS[obj['username']]
    message = obj['message']

    emit('new_private_message', message, room=recipient_session_id)


@SOCKETIO.on('join_room', namespace='/private')
def handle_join_room(room):
    join_room(room)
    emit('room_message', 'A new user has joined', room=room)


@SOCKETIO.on('leave_room', namespace='/private')
def handle_leave_room(room):
    leave_room(room)
    emit('room_message', 'A user left the room', room=room)


@APP.route('/close/<room>')
def close(room):
    close_room(room, namespace='/private')
    return 'The room has been terminated'


# This could be for a specific namespace too
@SOCKETIO.on('connect')
def on_connect():
    print('---------------> Connection estabilished')


@SOCKETIO.on('disconnect', namespace='/private')
def on_disconnect():
    print('---------------> Connection terminated')


@SOCKETIO.on('disconnect_me', namespace='/private')
def disconnect_me(message):
    disconnect()


if __name__ == '__main__':
    SOCKETIO.run(APP)
