from flask import Flask, render_template, request, session, redirect, url_for
import pymysql.cursors
import json
import numpy as np

app = Flask(__name__)

app.secret_key = '12345678'

# Intialize MySQL
connection = pymysql.connect(host='localhost',
                             user='root',
                             password='object@00',
                            #  database='PythonProject',
                             charset='utf8mb4',
                             cursorclass=pymysql.cursors.DictCursor)


@app.route('/')
def index():
    return render_template("index.html", login=True)


@app.route('/login', methods=["POST"])
def login():
    try:
        username = request.form["username"]
        password = request.form["password"]
        cursor = connection.cursor()

        sql = "SELECT * FROM pythonprojectusers.accounts WHERE username = %s AND password = %s"
        cursor.execute(sql, (username, password))
        result = cursor.fetchone()

        if result == None:
            return render_template('index.html', login=False)
        else:
            session['userId'] = result['id']
            tableData = getTableData()
            session['tableData'] = tableData
            listData = getProjectsList(session['userId'])
            return render_template('home.html', data = tableData, listData = listData)

    except Exception as e:
        connection.rollback()
        # print("Error: ", e)
    finally:
        print("done")

@app.route('/signup', methods=["POST", "GET"])
def signup():
    try:
        username = request.form["username"]
        password = request.form["password"]
        # connection = createConnection()
        cursor = connection.cursor()

        sql = "SELECT * FROM pythonprojectusers.accounts WHERE username = %s"
        cursor.execute(sql, (username, ))
        result = cursor.fetchone()
        if result == None:
            create_query = "INSERT INTO pythonprojectusers.accounts (username, password) VALUES (%s, %s)"
            cursor.execute(create_query, (username, password))

            return render_template('index.html', login=True)
        else:
            return render_template('index.html', exists=True)

    except Exception as e:
        connection.rollback()
        # print("Error: ", e)
    finally:
        connection.commit()
        print("done")

@app.route('/createProj', methods=["POST", "GET"])
def createProject():
    if "userId" not in session:
        return render_template("index.html", login=True)

    return render_template('home.html', project=True, data = session['tableData'], listData = getProjectsList(session['userId']))

@app.route('/editProj', methods=["POST", "GET"])
def editProject():
    if "userId" not in session:
        return render_template("index.html", login=True)

    try:
        jsonTableData = convertTableDatatoJSON(request.form)
        # jsonTableBind = convertTableDataBindtoJSON(request.form)
        projectId = request.form["projectId"]
        projectName = request.form["projectName"]
        vals = request.form["values"]
        temp = request.form["temperature"]
        unit = request.form["units"]
        action = request.form["action"].split(',')

        if action[0] == 'save' :
            cursor = connection.cursor()
            create_query = "UPDATE pythonproject.projects SET name = %s, vals = %s, temp = %s, unit = %s, data = %s WHERE id = %s"
            cursor.execute(create_query, (projectName, vals, temp, unit, jsonTableData, projectId))
        elif action[0] == 'saveProject' :
            cursor = connection.cursor()
            create_query = "INSERT INTO pythonproject.projects (name, vals, temp, unit, data, userId) VALUES (%s, %s, %s, %s, %s, %s)"
            cursor.execute(create_query, (projectName, vals, temp, unit, jsonTableData, session['userId']))

        if action[1] == 'true':
            calculatedData = calculateData(jsonTableData, vals, temp, unit)
            calculatedBindData = convertTableDataBindtoJSON(json.loads(calculatedData))
            return render_template('result.html', data = json.loads(calculatedData), bindData = json.loads(calculatedBindData),)
        else:
            return render_template('home.html', project=True, data = json.loads(jsonTableData), listData = getProjectsList(session['userId']), projId = projectId, projName = projectName, vals = vals, temp = temp, unit = unit)
    except Exception as e:
        connection.rollback()
        print("Error: ", e)
    finally:
        connection.commit()


@app.route('/getProjData', methods=["POST", "GET"])
def getProjectData():
    if "userId" not in session:
        return render_template("index.html", login=True)

    try:
        projectId = request.form["projectList"]
        tableData = session['tableData']
        cursor = connection.cursor()
        sql = "SELECT * FROM pythonproject.projects WHERE id = %s"
        cursor.execute(sql, (projectId))
        result = cursor.fetchone()
        if result == None:
            tableData = getTableData()
            listData = getProjectsList(session['userId'])
            return render_template('home.html', data = tableData, listData = listData)
        else:
            tableData = json.loads(result['data'])
            listData = getProjectsList(session['userId'])
            return render_template('home.html', project=True, data = tableData, listData = listData, projId= result['id'], projName= result['name'] if result['name'] else 'NEw', vals = result['vals'] if result['vals'] else '', temp = result['temp'] if result['temp'] else '', unit = result['unit'] if result['unit'] else '')
    except Exception as e:
        connection.rollback()
    finally:
        connection.commit()

@app.route('/calculate', methods=["POST", "GET"])
def calculateData():
    if "userId" not in session:
        return render_template("index.html", login=True)

    jsonTableData = convertTableDatatoJSON(request.form)
    jsonTableBind = convertTableDataBindtoJSON(request.form)
    print(jsonTableData)
    return render_template('result.html')

@app.route('/logout', methods=["GET"])
def logout():
    if "userId" not in session:
        return render_template("index.html", login=True)

    session.pop('userId', None)
    session.pop('tableData', None)
    session.pop('projectList', None)
    return redirect(url_for('index'))

@app.route('/back', methods=["GET"])
def back():
    if "userId" not in session:
        return render_template("index.html", login=True)

    return redirect(url_for('createProject'))


# @app.route('/getData', methods=["POST"])
def getTableData():
    try:
        sql = "SELECT * FROM pythonproject.tabledata"
        cursor = connection.cursor()
        cursor.execute(sql)
        result = cursor.fetchone()


    except Exception as e:
        connection.rollback()
        # print("Error: ", e)
    finally:
        connection.commit()
        global data
        data = json.loads(result['data'])
        return data

def getProjectsList(id):
    try:
        sql = "SELECT * FROM pythonproject.projects WHERE userId = %s"
        # print("here")
        cursor = connection.cursor()
        cursor.execute(sql, (id))
        result = cursor.fetchall()
        # print(result)
    except Exception as e:
        connection.rollback()
        # print("Error: ", e)
    finally:
        connection.commit()
        return result

def calculateData(data, values, temp, unit):
    jsonData = json.loads(data)

    calculateData = []
    for item in jsonData:
        dataDict = {
            'id': item['id'],
            'component': item['component'],
            'data1': (float(item['data1']) + 2) * float(values),
            'data2': (float(item['data2']) + 2) * float(values),
            'data3': (float(item['data3']) + 2) * float(values),
            'data4': (float(item['data4']) + 2) * float(values),
            'data5': (float(item['data5']) + 2) * float(values),
            'data6': (float(item['data6']) + 2) * float(values),
            'data7': (float(item['data7']) + 2) * float(values),
            'data8': (float(item['data8']) + 2) * float(values)
        }

        calculateData.append(dataDict)
    return json.dumps(calculateData)

def createConnection():
    return pymysql.connect(host='localhost',
                             user='root',
                             password='object@00',
                             database='PythonProject',
                             charset='utf8mb4',
                             cursorclass=pymysql.cursors.DictCursor)

def convertTableDatatoJSON(formData):
    tempTableData = np.array(list(formData.lists())[5][1])
    tableData2D = tempTableData.reshape(-1, 10)
    tableDataArray = []

    for row in tableData2D:
        rowDictionary = {
            'id': row[0],
            'component': row[1],
            'data1': row[2],
            'data2': row[3],
            'data3': row[4],
            'data4': row[5],
            'data5': row[6],
            'data6': row[7],
            'data7': row[8],
            'data8': row[9],
        }
        tableDataArray.append(rowDictionary)

    print(json.dumps(tableDataArray))
    return json.dumps(tableDataArray)

def convertTableDataBindtoJSON(tableDataArray):
    tableDataBind = []
    length = len(tableDataArray)
    keyLen= len(tableDataArray[0].keys())

    # outer loop for keys data1, data2...
    for row in range(1, keyLen-1):
        rowValues = []
        print(row)
        # inner loop for variant arrays
        for rowValue in range(1,length+1):
            rowValues.append(tableDataArray[rowValue-1]['data'+str(row)])
        
        tableDataBind.append(rowValues)

    return json.dumps(tableDataBind)

if __name__ == '__main__':
    app.run()