from flask import Flask, flash, request, redirect, send_from_directory, get_flashed_messages
import os
import glob
import securecad_parser
import datetime
from hooks import webhook, alarminator_api, cups_print
from pathlib import Path
from flask_basicauth import BasicAuth

app = Flask(__name__)
app.secret_key = 'super secret key'
app.config['SESSION_TYPE'] = 'filesystem'
app.config['BASIC_AUTH_USERNAME'] = 'admin'
app.config['BASIC_AUTH_PASSWORD'] = os.environ.get('BASIC_AUTH_PASSWORD','password')
basic_auth = BasicAuth(app)

def wrapHtml(innerHtml):
    return '''<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>JFW Alarm</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
  </head>
  <body><div class="container text-center">
  ''' + flashMessages() +'''
    ''' + innerHtml + '''
</div>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
  </body>
</html>'''

def flashMessages():
    messages = get_flashed_messages(with_categories=True)
    html = ""
    if messages:
        for category, message in messages:
            html = html + category + ": "+message+"<br>"
    return html

def alarmsPath():
    dir_path = os.path.dirname(os.path.realpath(__file__))
    return dir_path + "/alarms" + os.sep

def getAlarmFiles():
    a_list = glob.glob(alarmsPath()+"*.html")
    a_list.sort()
    return [os.path.basename(f) for f in a_list]

def parseAlarm(f):
    f = alarmsPath() + os.sep + f
    with open(f, "r") as o:
        _r: str = o.read()
        now = datetime.datetime.now()
        _r = _r.replace('%DATUM%',now.strftime("%d.%m.%Y"))
        _r = _r.replace('%UHRZEIT%',now.strftime("%H:%M"))
        if _r != '':
            return [securecad_parser.parse_securecad_message(_r),_r]
        
def allowed_file(filename:str):
    print(filename.rsplit('.', 1)[1].lower())
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ["html"]
            
        

@app.route("/")
@basic_auth.required
def root():
    html = ""
    file = request.args.get('sendalarm')
    if file is not None:
        parsed_body, raw = parseAlarm(file)
        if parsed_body != None:
            if 'ALARMDEPESCHE' in parsed_body:
                webhook(parsed_body)
                alarminator_api(parsed_body)
                cups_print(parsed_body,raw)
        flash("Alarm gesendet!")
        return redirect('/')

    html = html + '<div class="row align-items-start p-3 ">'
    i: str
    files = getAlarmFiles()
    for f in files:
        html = html + "<div class=\"col-6\" style='padding: 5px;'><a style='display:block; padding:20px' class=\"btn btn-block btn-danger\" href=\"/?sendalarm="+f+"\">" + f + "</a></div>"
    html =  html + "</div>"
    return wrapHtml(html)

@app.route('/files', methods=['POST'])
@basic_auth.required
def upload_file():
    # check if the post request has the file part
    print(request.files)
    if 'file' not in request.files:
        flash('No file part')
        return redirect(request.url)
    file = request.files['file']
    # If the user does not select a file, the browser submits an
    # empty file without a filename.
    print(file.filename)
    if file.filename == '':
        flash('No selected file')
        return redirect(request.url)
    if file and allowed_file(file.filename):
        file.save(os.path.join(alarmsPath(), file.filename))
    return redirect('/files')
    
@app.route('/files/<path:filename>', methods=['GET'])
@basic_auth.required
def download(filename):
    uploads = alarmsPath()
    return send_from_directory(uploads, filename, as_attachment=True)

@app.route("/files", methods=['GET'])
@basic_auth.required
def files():
    Path(alarmsPath()).mkdir(parents=True, exist_ok=True)
    file = request.args.get('del')
    if file is not None:
        try:
            os.remove(alarmsPath()+os.sep+file)
        except:
            pass
        flash("Datei gelöscht!")
        return redirect('/files')

    files = getAlarmFiles()
    html = '<ul class="list-group">'
    for f in files:
        html = html + '<li class="list-group-item"><a href="/files/'+f+'">'+f+'</a> <a href="/files?del='+f+'">löschen</a></li>'
    html = html + '</ul><form method="post" enctype="multipart/form-data"><input type="file" name="file"><input type=submit value=Upload></form>'
    return html

if __name__ == "__main__":
    app.run(port=5000)
