from flask import Blueprint, request, render_template, redirect, session, url_for, jsonify
import hashlib, psycopg2, process, MyDataclasses
from config import config, sites_config, setFirstSetupDone
from functools import wraps
from manage import create
from main import create_site, getUser, setSystemAdmin
import postsqldb

login_app = Blueprint('login', __name__)

def update_session_user():
    database_config = config()
    with psycopg2.connect(**database_config) as conn:
        user = postsqldb.LoginsTable.get_washed_tuple(conn, (session['user_id'],))
        session['user'] = user

def login_required(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        if 'user' not in session or session['user'] == None:
            return redirect(url_for('login.login'))
        return func(*args, **kwargs)
    return wrapper


@login_app.route('/setup', methods=['GET', 'POST'])
def first_time_setup():
    if request.method == "POST":
        database_address = request.form['database_address']
        database_port = request.form['database_port']
        database_name = request.form['database_name']
        database_user = request.form['database_user']
        database_password = request.form['database_address']

        site_manager = MyDataclasses.SiteManager(
            site_name=request.form['site_name'],
            admin_user=(request.form['username'], hashlib.sha256(request.form['password'].encode()).hexdigest(), request.form['email']),
            default_zone=request.form['site_default_zone'],
            default_location=request.form['site_default_location'],
            description=request.form['site_description']
        )

        process.addSite(site_manager)

        setFirstSetupDone()

        return redirect("/login")
    
    return render_template("setup.html")



@login_app.route('/logout', methods=['GET'])
def logout():
    if 'user' in session.keys():
        session['user'] = None
    return redirect('/login')

@login_app.route('/login', methods=['POST', 'GET'])
def login():
    session.clear()
    instance_config = sites_config()

    if instance_config['first_setup']:
        return redirect('/setup')

    if request.method == "POST":
        username = request.get_json()['username']
        password = request.get_json()['password']

        password = hashlib.sha256(password.encode()).hexdigest()
        database_config = config()
        with psycopg2.connect(**database_config) as conn:
            try:
                with conn.cursor() as cur:
                    sql = f"SELECT * FROM logins WHERE username=%s;"
                    cur.execute(sql, (username,))
                    user = cur.fetchone()
            except (Exception, psycopg2.DatabaseError) as error:
                conn.rollback()
                return jsonify({'error': True, 'message': str(error)})
        
        if user and user[2] == password:
            session['user_id'] = user[0]
            session['user'] = {'id': user[0], 'username': user[1], 'sites': user[13], 'site_roles': user[14], 'system_admin': user[15], 'flags': user[16]}
            return jsonify({'error': False, 'message': 'Logged In Sucessfully!'})
        else:
            return jsonify({'error': True, 'message': 'Username or Password was incorrect!'})

    
    if 'user' not in session.keys():
        session['user'] = None

    return render_template("other/login.html")

@login_app.route('/signup', methods=['POST', 'GET'])
def signup():
    instance_config = sites_config()
    if not instance_config['signup_enabled']:
        return jsonify({'error': True, 'message': 'It seems that Sign Ups are disabled by the server admin!'})

    if request.method == "POST":
        username = request.get_json()['username']
        password = request.get_json()['password']
        email = request.get_json()['email']
        password = hashlib.sha256(password.encode()).hexdigest()
        database_config = config()
        with psycopg2.connect(**database_config) as conn:
            try:
                with conn.cursor() as cur:
                    sql = f"INSERT INTO logins(username, password, email, row_type) VALUES(%s, %s, %s, %s);"
                    cur.execute(sql, (username, password, email, 'user'))
            except (Exception, psycopg2.DatabaseError) as error:
                conn.rollback()
                return jsonify({'error': True, 'message': str(error)})
        return jsonify({'error': False, 'message': 'You have been signed up successfully, you will have to wait until the server admin finishes your onboarding!'})
    return jsonify({'error': True, 'message': 'There was a problem with this POST request!'})
