import json
import os
from passlib.hash import scrypt
from pymongo.mongo_client import MongoClient
from pymongo.server_api import ServerApi
from dotenv import load_dotenv
import time

load_dotenv()

uri = os.getenv("MONGODB_URL")

# Create a new client and connect to the server
client = MongoClient(uri, server_api=ServerApi('1'))

# Send a ping to confirm a successful connection
try:
    client.admin.command('ping')
    print("Connected to MongoDB!")
except Exception as e:
    print(e)
    exit()

database = client[os.getenv("DATABASE_NAME")]
postsd = database[os.getenv("POST_COLLECTION")]
usersd = database[os.getenv("USER_COLLECTION")]
inboxd = database[os.getenv("INBOX_COLLECTION")]

class acc:
    def get(username):
        user = usersd.find_one({"username": username})
        if not user:
            return "notExists"
        else:
            return user
    
    def get_author(username):
        user = usersd.find_one({"username": username})
        if not user:
            return "notExists"
        else:
            del user["secure"]
            del user["profile"]
            return user

    def add(data, username=None):
        user = usersd.find_one({"username": username})
        if user:
            return "exists"
        try:
            usersd.insert_one(data)
        except Exception as e:
            return "fail"
        return True
    
    def edit(data, username):
        filter = { 'username': username }
        endr = { '$set': data }
        try:
            usersd.update_one(filter, endr)
        except Exception as e:
            print(e)
            return False
        return True

    def remove(username):
        user = usersd.find_one({"username": username})
        if not user:
            return "notExists"
        try:
            usersd.delete_one({"username": username})
        except:
            return "fail"
        return True

    def verify(token):
        user = usersd.find_one({"secure.token": token})
        if not user:
            return "notExists"
        if user["banned_until"] > round(time.time()):
            return {"banned": True, "username": user["username"]}
        else:
            return {"banned": False, "username": user["username"]}

    def verify_pswd(username, password):
        user = usersd.find_one({"username": username})
        if not user:
            return "notExists"
        if user["banned_until"] > round(time.time()):
            return "banned"
        elif not scrypt.verify(password, user["secure"]["password"]):
            return "unauthorized"
        else:
            return {"token": user["secure"]["token"]}

    def get_ban(username):
        user = usersd.find_one({"username": username})
        if not user:
            return "notExists"
        return {"banned_until": user["banned_until"], "ban_reason": user["secure"]["ban_reason"]}

    def get_perms(username):
        user = usersd.find_one({"username": username})
        if not user:
            return "notExists"
        return user["permissions"]

class posts:
    def get_recent(amount=75):
        posts = list(postsd.find().sort("created", -1).limit(amount))
        for i in posts:
            data = acc.get(i["author"])
            if type(data) != dict:
                data = {}
            else:
                del data["secure"]
                del data["profile"]
            i["author"] = data
            incr = -1
            for j in i["replies"]:
                incr += 1
                data = acc.get(j["author"])
                if type(data) != dict:
                    data = {}
                else:
                    del data["secure"]
                    del data["profile"]
                i["replies"][incr]["author"] = data
        return posts
    
    def get_by_id(post_id, supply_author=False):
        post = postsd.find_one({"_id": post_id})
        if not post:
            return "notExists"
        if supply_author:
            data = acc.get(post["author"])
            if type(data) != dict:
                data = {}
            else:
                del data["secure"]
                del data["profile"]
            post["author"] = data
            incr = -1
            for j in post["replies"]:
                incr += 1
                data = acc.get(j["author"])
                if type(data) != dict:
                    data = {}
                else:
                    del data["secure"]
                    del data["profile"]
                post["replies"][incr]["author"] = data
        return post

    def add(data):
        try:
            postsd.insert_one(data)
        except Exception as e:
            return "fail"
        return True

class inbox:
    def get_recent(amount=75):
        posts = list(inboxd.find().sort("created", -1).limit(amount))
        return posts
    
    def add(data):
        try:
            inboxd.insert_one(data)
        except Exception as e:
            return "fail"
        return True