import asyncio
import websockets
import mysql.connector
import json

sensorNodeArray = []
enqueteNodeArray = []

async def processSensorNodeData(data, nodeID):
    try:
        mydb = dbLogin()
        cursor = mydb.cursor()

        query = "INSERT INTO `Measurement` (NodeID, Type, Value) VALUES (%s, %s, %s)"
        processedData = json.loads(data)

        processedTemp = (processedData['Temp'])
        processedHumi = (processedData['Humi'])
        processedeCO2 = (processedData['eCO2'])
        processedTVOC = (processedData['TVOC'])
        processedMAC = (processedData['node'])

        pushingDataArray = [(nodeID, "Temp", processedTemp), (nodeID, "Humi", processedHumi), (nodeID, "eCO2", processedeCO2), (nodeID, "TVOC", processedTVOC)]
        for i in pushingDataArray:
            print(query ,i)
            cursor.execute(query, i)
            mydb.commit()
            
    except mysql.connector.Error as err:
        print("MySQL Error:", err)
    finally:
        cursor.close()
        mydb.close()
        
async def processEnqueteNodeData(data, nodeID):
    try:
        mydb = dbLogin()
        cursor = mydb.cursor()

        query = "INSERT INTO `Reply` (Result, Node_NodeID, Question_QuestionID) VALUES (%s, %s, %s)"
        processedData = json.loads(data)

        processedQuestionID = (processedData['QuestionID'])
        processedResponse = (processedData['Response'])

        pushingDataArray = [(processedResponse, nodeID, processedQuestionID)]

        for i in pushingDataArray:
            cursor.execute(query, i)
            mydb.commit()
    except mysql.connector.Error as err:
        print("MySQL Error:", err)
    finally:
        cursor.close()
        mydb.close()

async def receive_data():
    uri = "ws://145.92.8.114/ws"
    try:
        async with websockets.connect(uri) as websocket:
            while True:
                data = await websocket.recv()
                print(f"Received data: {data}")

                processedData = json.loads(data)
                macAdress = processedData['node']

                if "Temp" in processedData:
                    type = 'sensor'
                else:
                    type = 'enquete'

                await getNodeInfo('sensor')
                await getNodeInfo('enquete')

                print(sensorNodeArray)
                
                if macAdress in sensorNodeArray:
                    nodeID = await getNodeID(macAdress)
                    await processSensorNodeData(data, nodeID)
                elif macAdress in enqueteNodeArray:
                    nodeID = await getNodeID(macAdress)
                    await processEnqueteNodeData(data, nodeID)
                else: 
                    await newNode(macAdress, type)
    except websockets.ConnectionClosedError as e:
        print("WebSocket connection closed:", e)

async def main():
    await receive_data()

def dbLogin():
    mydb = mysql.connector.connect(
        host="localhost",
        user="root",
        password="Dingleberries69!",
        database="NodeData" 
    )

    return mydb

async def getNodeInfo(type):
    global sensorNodeArray
    global enqueteNodeArray

    nodeInfoArray = []

    id = (type,)
    mydb = dbLogin()
    cursor = mydb.cursor()
    cursor.execute("""SELECT MAC FROM Node WHERE Type = %s""", id)
    nodeInfo = cursor.fetchall()

    for tuples in nodeInfo:
        for item in tuples:
            nodeInfoArray.append(item)
    print(nodeInfoArray)
    
    cursor.close()
    mydb.close()
    
    if type == 'sensor':
        sensorNodeArray = nodeInfoArray
        print(sensorNodeArray)
        return sensorNodeArray

    elif type == 'enquete':
        enqueteNodeArray = nodeInfoArray
        return enqueteNodeArray


async def getNodeID(macAdress):
    id = (macAdress,)
    mydb = dbLogin()
    cursor = mydb.cursor()
    cursor.execute("""SELECT nodeID FROM Node WHERE MAC = %s""", id)
    data = cursor.fetchall()

    for tuples in data:
        for item in tuples:
            nodeID = item

    return nodeID

async def newNode(mac, type):
    id = (mac, type,)
    mydb = dbLogin()

    cursor = mydb.cursor()
    cursor.execute("INSERT INTO `Node` (MAC, Type) VALUES (%s, %s)", id)
    print("new node assigned")
    mydb.commit()

asyncio.run(main())