import express from "express";
import mustache from "mustache";
import bodyParse from "body-parser";
import { readdirSync, readFileSync } from "fs";
import { Server } from "socket.io";
import http from "http";

const app = express();
app.use(express.static("./static"));
app.use(bodyParse.urlencoded({ extended: true }));
const port = 9779;
const server = http.createServer(app);
const io = new Server(server);

class Room {
    id = 0
    history = []

    static newRoom() {
        const room = new Room();
        room.id = db.roomsCount++;
        db.rooms.push(room);
        return room;
    }

    /**
     * 
     * @param {String} type 
     * @param {Array.<Any>} params 
     */
    addCmd(type, params) {
        this.history.push([Date.now(), type, params]);
    }
}

const db = {
    roomsCount: 0,
    /** @type {Array.<Room>} */
    rooms: [],

    /**
     * 
     * @param {Number} roomId 
     */
    findRoom(roomId) {
        let room = null;
        for (let _room of db.rooms) {
            if (_room.id === roomId) {
                room = _room;
            }
        }
        return room;
    }
};

const templates = new Map(readdirSync("./templates").map(fn => [fn, readFileSync(`./templates/${fn}`, "utf-8")]));

app.get("/", (req, res) => {
    res.send(mustache.render(templates.get("mainPage.html"), { db }));
});

app.get("/createRoom", (req, res) => {
    let room = Room.newRoom();
    res.redirect(`/room/${room.id}`);
});

app.get("/room/:roomId", (req, res) => {
    let room = db.findRoom(parseInt(req.params.roomId));

    if (room === null) {
        res.redirect("/");
    } else {
        res.send(mustache.render(templates.get("roomPage.html"), { room }));
    }
});

io.on("connection", (socket) => {
    socket.on("draw", (data) => {
        console.log(`data: ${JSON.stringify(data)}`);
        let room = db.findRoom(parseInt(data.roomId));
        if (room === null) {
            console.error(`No room with id ${data.roomId}!`);
        } else {
            room.addCmd(data.type, data.params);
            io.emit("draw_sync", data);
        }
    });

    socket.on("sync_me", (data) => {
        console.log(`data: ${JSON.stringify(data)}`);
        let room = db.findRoom(parseInt(data.roomId));
        if (room === null) {
            console.error(`No room with id ${data.roomId}!`);
        } else {
            socket.emit("sync_history", { roomId: data.roomId, history: room.history });
        }
    });
});

server.listen(port, () => console.log(`⚡️ Serving on port ${port}`));