from flask import Flask, render_template, request, redirect, url_for, jsonify, session
import sqlite3
import bcrypt

app = Flask(__name__)
app.secret_key = 'supersecretkey'

# Database setup
def init_db():
    conn = sqlite3.connect('database.db')
    c = conn.cursor()
    c.execute('''CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, username TEXT, password TEXT)''')
    c.execute('''CREATE TABLE IF NOT EXISTS printers (id INTEGER PRIMARY KEY, name TEXT, status TEXT)''')
    c.execute('''CREATE TABLE IF NOT EXISTS jobs (id INTEGER PRIMARY KEY, printer_id INTEGER, user TEXT, date TEXT, status TEXT)''')
    conn.commit()
    conn.close()

init_db()

# User registration (Admin setup)
def add_admin():
    conn = sqlite3.connect('database.db')
    c = conn.cursor()
    hashed_pw = bcrypt.hashpw('adminpassword'.encode('utf-8'), bcrypt.gensalt())
    c.execute("INSERT INTO users (username, password) VALUES (?, ?)", ('admin', hashed_pw))
    conn.commit()
    conn.close()

# Comment the next line after the first run
# add_admin()

# API Endpoints
@app.route('/api/printers/status', methods=['GET'])
def get_printer_status():
    conn = sqlite3.connect('database.db')
    c = conn.cursor()
    c.execute("SELECT * FROM printers")
    printers = c.fetchall()
    conn.close()
    return jsonify(printers)

@app.route('/api/printers/job', methods=['POST'])
def create_job():
    if not session.get('logged_in'):
        return jsonify({'error': 'Unauthorized'}), 403

    data = request.json
    user = session['username']
    printer_id = data['printer_id']
    conn = sqlite3.connect('database.db')
    c = conn.cursor()

    c.execute("SELECT status FROM printers WHERE id=?", (printer_id,))
    status = c.fetchone()[0]

    if status == 'frei':
        c.execute("INSERT INTO jobs (printer_id, user, date, status) VALUES (?, ?, datetime('now'), 'in progress')", 
                  (printer_id, user))
        c.execute("UPDATE printers SET status='belegt' WHERE id=?", (printer_id,))
        conn.commit()
    elif status == 'belegt':
        return jsonify({'error': 'Printer already in use'}), 409
    else:
        return jsonify({'error': 'Invalid printer status'}), 400

    conn.close()
    return jsonify({'message': 'Job created and printer turned on'}), 200

@app.route('/api/printers/reserve', methods=['POST'])
def reserve_printer():
    if not session.get('logged_in'):
        return jsonify({'error': 'Unauthorized'}), 403

    data = request.json
    printer_id = data['printer_id']
    conn = sqlite3.connect('database.db')
    c = conn.cursor()

    c.execute("SELECT status FROM printers WHERE id=?", (printer_id,))
    status = c.fetchone()[0]

    if status == 'frei':
        c.execute("UPDATE printers SET status='reserviert' WHERE id=?", (printer_id,))
        conn.commit()
        message = 'Printer reserved'
    else:
        message = 'Printer cannot be reserved'

    conn.close()
    return jsonify({'message': message}), 200

@app.route('/api/printers/release', methods=['POST'])
def release_printer():
    if not session.get('logged_in'):
        return jsonify({'error': 'Unauthorized'}), 403

    data = request.json
    printer_id = data['printer_id']
    conn = sqlite3.connect('database.db')
    c = conn.cursor()

    c.execute("UPDATE printers SET status='frei' WHERE id=?", (printer_id,))
    conn.commit()
    conn.close()
    return jsonify({'message': 'Printer released'}), 200

# Authentication routes
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password'].encode('utf-8')

        conn = sqlite3.connect('database.db')
        c = conn.cursor()
        c.execute("SELECT * FROM users WHERE username=?", (username,))
        user = c.fetchone()
        conn.close()

        if user and bcrypt.checkpw(password, user[2].encode('utf-8')):
            session['logged_in'] = True
            session['username'] = username
            return redirect(url_for('dashboard'))
        else:
            return render_template('login.html', error='Invalid Credentials')

    return render_template('login.html')

@app.route('/dashboard')
def dashboard():
    if not session.get('logged_in'):
        return redirect(url_for('login'))

    conn = sqlite3.connect('database.db')
    c = conn.cursor()
    c.execute("SELECT * FROM printers")
    printers = c.fetchall()
    conn.close()

    return render_template('dashboard.html', printers=printers)

@app.route('/logout')
def logout():
    session.clear()
    return redirect(url_for('login'))

if __name__ == '__main__':
    app.run(debug=True)
