import * as express from "express";
import {createServer, Server as HTTPServer} from "http";
import * as path from "path";
import * as mysql from "mysql";

export class Server {
    private httpServer: HTTPServer;
    private app: express.Application;
    private mysqlConnection;
    // private io: socketIO.Server;

    // private activeSockets: string[] = [];
    // private senders: string[] = [];

    private readonly DEFAULT_PORT = parseInt(process.env.PORT) || 5000;

    constructor() {

        this.initialize();
    }

    private initialize(): void {
        this.app = express();
        this.httpServer = createServer(this.app);
        this.mysqlConnection = mysql.createConnection({
            host: process.env.MYSQL_HOST || "localhost",
            user: process.env.MYSQL_USER || "root",
            password: process.env.MYSQL_PASSWORD || "",
            database: process.env.MYSQL_DATABASE || "hochzeit"
        });

        this.configureApp();
        this.configureRoutes();
        // this.handleSocketConnection();
    }

    private async query(sql): Promise<any[]> {
        return new Promise((resolve, reject) => {
            this.mysqlConnection.query(sql, (error, results) => {
                if (error) {
                    reject(error)
                } else {
                    resolve(results);
                }
            })
        })
    }

    private configureApp(): void {
        this.app.use(express.json({limit: "1mb"}));
        this.app.use(express.static(path.join(__dirname, "../../dist")));
    }

    private configureRoutes(): void {
        this.app.get("/", (req, res) => {
            res.sendFile("index.html");
        });
        this.app.get("/presents", async (req, res) => {
            res.json(await this.query("SELECT * FROM presents"));
        })
        this.app.post("/presents", async (req, res) => {
            const id = parseInt(req.body.id);
            const isBought = (req.body.isBought === true)?1:0;
            const version = parseInt(req.body.version) || 0;
            const newVersion = version + 1;

            const presents = await this.query("SELECT * FROM presents WHERE id = '" + id + "'");
            if (presents.length === 0) {
                await this.query("INSERT INTO presents (id, isBought, version) VALUES (" + id + ", " + isBought + ", " + newVersion + ");");
            } else {
                const present = presents[0];
                if (present.version === version) {
                    await this.query("UPDATE presents SET version = " + newVersion + ", isBought = " + isBought + " WHERE ID = " + id);
                } else {
                    return res.json({"success": false, "error": "wrong-version", present: present});
                }
            }
            return res.json({"success": true, present: {id: id, isBought: isBought, version: newVersion}})
        })
    }

    public listen(callback: (port: number) => void): void {
        this.httpServer.listen(this.DEFAULT_PORT, () => {
            callback(this.DEFAULT_PORT);
        });
    }
}