import uuid

import requests
import simplejson
from bson import ObjectId
from pymongo import MongoClient


class DatabaseUtils(object):
    def __init__(self, dbconfig, fbaccesstoken):
        self.dbconfig = dbconfig
        self.fbaccesstoken = fbaccesstoken
        client = MongoClient(dbconfig['host'], dbconfig['port'])
        # client.drop_database(constants.DATABASE_NAME)
        self.db = client[dbconfig['name']]

    def get_user(self, sender):
        """Returns user object from database."""
        user = self.db.User
        current_sender = None
        current_user = user.find({
            'user_id': str(sender)})
        for document in current_user:
            current_sender = document
        if current_sender is None:
            if sender.isdigit():
                current_sender = self.generate_new_fb_user(sender)
            else:
                current_sender = self.generate_new_user()
        return current_sender

    def generate_new_fb_user(self, sender):
        """Generates new Facebook user in database."""
        user = self.db.User
        current_sender = None
        try:
            resp = requests.get(
                'https://graph.facebook.com/v2.6/' + sender + '?access_token=' + self.fbaccesstoken)
            fb_user = simplejson.loads(str(resp.text))
            current_sender = dict()
            current_sender['_id'] = ObjectId()
            current_sender["is_input_expected"] = False
            current_sender["expected_input"] = ""
            current_sender['user_id'] = sender
            if fb_user.get('first_name'):
                current_sender['first_name'] = fb_user['first_name']
            if fb_user.get('last_name'):
                current_sender['last_name'] = fb_user['last_name']
            if fb_user.get('gender'):
                current_sender['gender'] = fb_user['gender']
            if fb_user.get('locale'):
                current_sender['locale'] = fb_user['locale']
            user.insert(current_sender)
            print('Created new user: {0}'.format(current_sender['user_id']))
        except:
            print('Error creating new user')
        return current_sender

    def generate_new_user(self):
        """Generates new user in database."""
        user = self.db.User
        user_id = uuid.uuid4().urn[9:]
        print('generated user = {0}'.format(user_id))
        current_sender = None
        current_user = user.find({
            'user_id': str(user_id)})
        for document in current_user:
            current_sender = document
        if current_sender is None:
            try:
                current_sender = self.constants.USER_OBJECT
                current_sender['user_id'] = user_id
                current_sender["is_input_expected"] = False
                current_sender["expected_input"] = ""
                print('Created new user: {0}'.format(user.insert_one(current_sender).inserted_id))
            except:
                print('Error creating new user')
        return current_sender

    def update_user(self, sender, data_for_update):
        """Updates user object in database."""
        self.db.User.update_one({
            'user_id': sender
        }, {
            '$set': data_for_update
        }, upsert=False)

    def is_input_expected(self, sender):
        """Checks if input is expected."""
        user = self.db.User
        current_user = user.find({
            "user_id": str(sender)})
        is_expected = False
        try:
            for document in current_user:
                is_expected = document["is_input_expected"]
        except:
            return False
        return is_expected

    def get_expected_input_type(self, sender):
        """Returns expected input type."""
        user = self.db.User
        current_user = user.find({
            "user_id": str(sender)})
        expected_input = ""
        for document in current_user:
            expected_input = document["expected_input"]
        return expected_input