from .db import db
from . import app, users

import time
import json
from flask import request, jsonify

rooms = db["rooms"]
rooms.create_index("name", unique=True)

def create_room(name, creator, publicity="public"):
    room = {
        "name": name,
        "creator": creator["login"].lower(),
        "description": "A description",
        "theme": {
            "background_colour": "#00BCD4",
            "logo-src": "/static/images/logo.png"
        },
        "users": {
            creator["login"].lower(): {
                "rank": "owner",
                "tag": "owner",
                "banned": False,
                "muted": False,
                "last_message": -1,
            }
        },
        "publicity": publicity,
        "created": time.time(),
        "tags": {
            "default": {
                "name": "User",
                "colour": "#00BCD4",
            },
            "owner": {
                "name": "Owner",
                "colour": "#EEEEEE",
            }
        }
    }
    try:
        rooms.insert(room)
    except ValueError:
        return False

    return True


def get_room(room_name):
    return rooms.find_one({"name": room_name})


def add_user(room_name, username):
    return rooms.update_one(
        {"name": room_name},
        {
            "$set": {
                "users.%s" % username.lower(): {
                    "rank": "default",
                    "tag": "default",
                    "banned": False,
                    "muted": False,
                    "last_message": -1,
                    "online": False,
                    "last_ping": -1
                }
            }
        }
    )

def remove_user(room_name, username):
    return rooms.update_one(
        {"name": room_name},
        {"$unset": {"users.%s" % username.lower(): ""}},
    )


def invite_user(room_name, username):
    return rooms.update_one(
        {"name": room_name},
        {"$push": {"invited": username}}
    )


def get_user_in_room(room, user):
    try:
        return room["users"][user["username"].lower()]
    except KeyError:
        return None


def update_last_message(room_name, username, timestamp=None):
    if timestamp is None:
        timestamp = time.time()

    return rooms.update_one(
        {"name": room_name},
        {
            "$set": {
                ("users.%s.last_message" % username.lower()): timestamp,
                ("users.%s.last_ping" % username.lower()): timestamp,
                ("users.%s.online") % username.lower(): True
            }
        }
    )

def update_last_ping(room_name, username, timestamp=None):
    if timestamp is None:
        timestamp = time.time()

    return rooms.update_one(
        {"name": room_name},
        {
            "$set": {
                ("users.%s.last_ping" % username.lower()): timestamp,
                ("users.%s.online") % username.lower(): True
            }
        }
    )


def ban_user(room_name, username):
    return rooms.update_one(
        {"name": room_name},
        {
            "$set": {
                ("users.%s.banned" % username.lower()): True
            }
        }
    )


def unban_user(room_name, username):
    return rooms.update_one(
        {"name": room_name},
        {
            "$set": {
                ("users.%s.banned" % username.lower()): False
            }
        }
    )


def set_tag(room_name, username, tag):
    return rooms.update_one(
        {"name": room_name},
        {
            "$set": {
                ("users.%s.tag" % username.lower()): tag
            }
        }
    )


def get_tag(room, user):
    try:
        return room["users"][user]["tag"]
    except:
        return "default"



def remove_tag(room_name, username):
    return rooms.update_one(
        {"name": room_name},
        {
            "$set": {
                ("users.%s.tag" % username.lower()): "default"
            }
        }
    )


def set_user_online(room_name, username, online):
    return rooms.update_one(
        {"name": room_name},
        {
            "$set": {
                ("users.%s.online" % username.lower()): online
            }
        }
    )


def get_valid_tags(room_name):
    room = rooms.find_one({"name": room_name}, {"tags": 1})
    try:
        return room["tags"]
    except:
        return {
            "ok": False,
            "message": "Room not found.",
        }


def set_valid_tags(room_name, tags):
    return rooms.update_one(
        {"name": room_name},
        {"$set": {"tags": tags}}
    )


def safe_room(room):
    return {
        "name": room["name"],
        "creator": room["creator"],
        "description": room["description"],
        "created": room["created"]
    }

@app.template_global()
def list_rooms(username=None):
    res = rooms.find(
        {
            "$or": [
                {"publicity": "public"},
                {"users.%s.banned" % username.lower(): False} if username else {"": True},
                {"invited": {"$in": [username.lower()]}},
            ]
        },
        {"name":1, "creator": 1, "description": 1, "created": 1}
    )

    safe_rooms = {}
    for room in res:
        safe_rooms[room["name"]] = safe_room(room)