import shutil
import qrcode
import zipfile
import datetime
import os
import mysql.connector
from flask import Flask, render_template, request, send_file

app = Flask(__name__, static_folder="static", template_folder=os.getcwd())

url = "http://localhost:1228/"

# MySQL database connection
db = mysql.connector.connect(
    host="127.0.0.1",
    user="root",
    password="mayura1234",
    database="file_transfer"
)

# MySQL cursor for executing queries
cursor = db.cursor()

# This function is created to delete first 4 files in the directory to sustain server space
def dtl():
    try:
        k = os.listdir()
        for i in k:
            if k.index(i) != 4:
                if (".zip" in i):
                    os.remove(i)
            else:
                break
    except Exception as sr:
        print(sr)

def rdm():
    import random
    return str(random.randint(100000, 999999))

@app.route("/", methods=["GET"])
def a1():
    dtl()
    return render_template("index.html")

@app.route("/send", methods=["GET", "POST"])
def a3():
    if request.method == "POST":
        g = request.files.getlist("files[]")
        h = rdm()  # random number is generated
        os.mkdir(f"files/{h}")  # folder is created by name of that random number and files uploaded are stored in it
        qrcode.make(f"{url}/data/{h}/").save(f"files/{h}/qrcode.png")
        
        # Save each file
        for i in g:
            i.save(f"files/{h}/{i.filename}")
        
        # Insert file details into the MySQL database
        for i in g:
            cursor.execute("INSERT INTO files (file_id, file_name) VALUES (%s, %s)", (h, i.filename))
        db.commit()  # Commit the transaction to save the data
        
        return render_template("post.html", file_id=h)
    else:
        return render_template("send.html")

@app.route("/recieve", methods=["GET", "POST"])
def a4():
    if request.method == "GET":
        return render_template("recieve.html", err="none")
    else:
        # In this function if the directory name with that download ID exists then the folder is converted into zip and sent to client
        nm = request.form["id"]

        # Query MySQL to check if the file_id exists
        cursor.execute("SELECT * FROM files WHERE file_id = %s", (nm,))
        result = cursor.fetchall()

        if result:
            zp = zipfile.ZipFile(f"{nm}.zip", 'w') 
            for i in os.listdir(f"files/{nm}"):
                zp.write(f"files/{nm}/{i}")
            zp.close()
            shutil.rmtree(f"files/{nm}")
            return send_file(f"{nm}.zip")
        else:
            return render_template("recieve.html", err="No file(s) available")

@app.route("/files/<id>/qrcode.png", methods=["GET"])
def a6(id):
    try:
        return send_file(f"files/{id}/qrcode.png")  # function for generating QR code for download link
    except:
        return "404"

@app.route("/data/<nm>")
def a7(nm):
    # Query MySQL to check if the file_id exists
    cursor.execute("SELECT * FROM files WHERE file_id = %s", (nm,))
    result = cursor.fetchall()

    if result:
        zp = zipfile.ZipFile(f"{nm}.zip", 'w') 
        for i in os.listdir(f"files/{nm}"):
            zp.write(f"files/{nm}/{i}")
        zp.close()
        shutil.rmtree(f"files/{nm}")
        return send_file(f"{nm}.zip")
    else:
        return render_template("recieve.html", err="No file(s) available")

# Adding custom 404 error template
@app.errorhandler(404)
def a12(e):
    return render_template("err.html", err="404")

# Error handling of internal server error
@app.errorhandler(501)
def a12(e):
    return render_template("err.html", err="501")

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=1228)