from flask import request, redirect, session, render_template, send_from_directory, Flask
from os import path, walk

import hashlib

import configparser

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import scoped_session,sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.sql import text

config = configparser.ConfigParser()
config.read('config.ini')

instanceBranding = str(config['BRANDING']['instanceName'])
instanceLocation = str(config['BRANDING']['instanceLocation'])

databaseUsername = str(config['DATABASE']['username'])
databasePassword = str(config['DATABASE']['password'])
databaseName = str(config['DATABASE']['name'])

engine = create_engine(f"postgresql://{databaseUsername}:{databasePassword}@localhost/{databaseName}")
db = scoped_session(sessionmaker(bind=engine))

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    username = Column(String, unique=True, nullable=False)
    password = Column(String, nullable=False)

Base.metadata.create_all(engine)

app = Flask(__name__)

def encrypt(data):
    hash = hashlib.sha512()
    data = data.encode('utf-8')
    hash.update(data)
    hash = hash.hexdigest()
#    print(str(hash))
    return hash

#encrypt("hi")

@app.route('/')
def home():
    return render_template('index.j2', instanceLocation=instanceLocation, instanceBranding=instanceBranding)


@app.route('/auth/login/', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = encrypt(request.form['password'])

        user = db.execute(text("SELECT * FROM users WHERE username = :username AND password = :password"),
                          {"username": username, "password": password}).fetchone()

        if user:
            session['user_id'] = user.id
            return redirect('/')
        else:
            return "invalid credentials 😾"
    return render_template('login.j2', instanceLocation=instanceLocation, instanceBranding=instanceBranding)

@app.route('/auth/register/', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        username = request.form['username']
        password = encrypt(request.form['password'])
        print(username)

        # check if username exists
        existing_user = db.execute(text("SELECT * FROM users WHERE username = :username"),
                                   {"username": username}).fetchone()
        if existing_user:
            return "that user already exists 😾"

        # insert new user
        db.execute(text("INSERT INTO users (username, password) VALUES (:username, :password)"),
                   {"username": username, "password": password})
        db.commit()
        return redirect('/auth/login/')  # redirect to login page after successful registration
    return render_template('register.j2', instanceLocation=instanceLocation, instanceBranding=instanceBranding)

@app.route('/auth/logout/')
def logout():
    session.pop('user_id', None)
    return redirect('/')

@app.route('/assets/css/index.css')
def index_css():
    return send_from_directory('static/assets/css', 'index.css')


extra_dirs = ['app/templates', 'static/assets/css']
extra_files = extra_dirs[:]
for extra_dir in extra_dirs:
    for dirname, dirs, files in walk(extra_dir):
        for filename in files:
            filename = path.join(dirname, filename)
            if path.isfile(filename):
                extra_files.append(filename)

if __name__ == '__main__':
    app.secret_key = 'super secret key'
    app.run(debug=True, extra_files=extra_files)