/**
 * ==================================================
 * Smart Attendance System
 * Device API Tester
 * ==================================================
 */

require("dotenv").config();

const axios = require("axios");
const readline = require("readline");

const BASE_URL = "http://localhost:5000/api/devices";

const rl = readline.createInterface({

    input: process.stdin,

    output: process.stdout

});

function ask(question) {

    return new Promise(resolve =>

        rl.question(question, resolve)

    );

}

async function pause() {

    await ask("\nPress ENTER to continue...");

}

function menu() {

    console.clear();

    console.log("============================================================");
    console.log("           Smart Attendance Device Tester");
    console.log("============================================================");
    console.log("1. Register Device");
    console.log("2. Get All Devices");
    console.log("3. Get Device By ID");
    console.log("4. Update Device");
    console.log("5. Delete Device");
    console.log("6. Verify Device");
    console.log("0. Exit");
    console.log("============================================================");

}

async function registerDevice() {

    console.clear();

    console.log("Register Device");
    console.log("============================================================");

    const device_id = await ask("Device ID        : ");
    const device_name = await ask("Device Name      : ");
    const location = await ask("Location         : ");

    try {

        const response = await axios.post(

            BASE_URL,

            {

                device_id,

                device_name,

                device_type: "ESP32_CAM_NFC",

                serial_number: "",

                location,

                room: "",

                firmware_version: "1.0.0"

            }

        );

        console.log("\n✔ Device Registered\n");

        console.log(response.data);

    }

    catch (err) {

        console.log("\n✖ Registration Failed\n");

        console.log(

            err.response ?

            err.response.data :

            err.message

        );

    }

    await pause();

}

async function getAllDevices() {

    console.clear();

    console.log("All Devices");
    console.log("============================================================");

    try {

        const response = await axios.get(

            BASE_URL

        );

        console.table(

            response.data.data

        );

    }

    catch (err) {

        console.log(err.message);

    }

    await pause();

}

async function getDeviceById() {

    console.clear();

    console.log("Get Device");
    console.log("============================================================");

    const id = await ask("Device ID : ");

    try {

        const response = await axios.get(

            `${BASE_URL}/${id}`

        );

        console.log(response.data);

    }

    catch (err) {

        console.log(

            err.response ?

            err.response.data :

            err.message

        );

    }

    await pause();

}

async function updateDevice() {

    console.clear();

    console.log("Update Device");
    console.log("============================================================");

    const id = await ask("Database ID : ");

    const device_name = await ask("New Name : ");

    const location = await ask("Location : ");

    try {

        const oldDevice = await axios.get(

            `${BASE_URL}/${id}`

        );

        const d = oldDevice.data.data;

        const response = await axios.put(

            `${BASE_URL}/${id}`,

            {

                device_name,

                device_type: d.device_type,

                serial_number: d.serial_number,

                location,

                room: d.room,

                ip_address: d.ip_address,

                mac_address: d.mac_address,

                firmware_version: d.firmware_version,

                status: d.status

            }

        );

        console.log(response.data);

    }

    catch (err) {

        console.log(

            err.response ?

            err.response.data :

            err.message

        );

    }

    await pause();

}

async function deleteDevice() {

    console.clear();

    console.log("Delete Device");
    console.log("============================================================");

    const id = await ask("Database ID : ");

    try {

        const response = await axios.delete(

            `${BASE_URL}/${id}`

        );

        console.log(response.data);

    }

    catch (err) {

        console.log(

            err.response ?

            err.response.data :

            err.message

        );

    }

    await pause();

}

async function verifyDevice() {

    console.clear();

    console.log("Verify Device");
    console.log("============================================================");

    const device_id = await ask("Device ID : ");

    const api_key = await ask("API Key   : ");

    try {

        const response = await axios.post(

            `${BASE_URL}/verify`,

            {

                device_id,

                api_key

            }

        );

        console.log(response.data);

    }

    catch (err) {

        console.log(

            err.response ?

            err.response.data :

            err.message

        );

    }

    await pause();

}

async function main() {

    while (true) {

        menu();

        const option = await ask("\nSelect Option : ");

        switch (option) {

            case "1":

                await registerDevice();

                break;

            case "2":

                await getAllDevices();

                break;

            case "3":

                await getDeviceById();

                break;

            case "4":

                await updateDevice();

                break;

            case "5":

                await deleteDevice();

                break;

            case "6":

                await verifyDevice();

                break;

            case "0":

                rl.close();

                process.exit(0);

                break;

            default:

                console.log("Invalid Option.");

                await pause();

        }

    }

}

main();