/**
 * Resources:
 * https://deepinder.me/creating-a-real-time-chat-app-with-vue-socket-io-and-nodejs-2
 * https://socket.io/docs/v4/server-api/
 */

import express from 'express';
import { Server } from 'socket.io';
import http from 'http';
import { createUser, validateUser } from './models/user';
import cors from 'cors';  // Import cors


const app = express();
const server = http.createServer(app);
const io = new Server(server, { cors: { origin: '*' } });

app.use(cors());  // Enable cors
app.use(express.json());

// Simple user registration endpoint
app.post('/register', async (req, res) => {
    const { username, password } = req.body;
    try {
        await createUser(username, password);
        res.status(201).send('User registered');
    } catch (error) {
        res.status(500).send('Error registering user');
    }
});

// Simple login endpoint
app.post('/login', async (req, res) => {
    const { username, password } = req.body;
    if (await validateUser(username, password)) {
        res.send('Login successful');
    } else {
        res.status(401).send('Invalid credentials');
    }
});

const playerList: any = [];

// Socket.IO authentication and room management
io.on('connection', (socket) => {
    const { username, password } = socket.handshake.query;

    if (!username || !password) {
        socket.disconnect(true);
        return;
    }

    if (!validateUser(<string> username, <string> password)) {
        socket.disconnect(true);
        return;
    }

    // add player to playerList but only if they are not already in the list
    if (!playerList.find((player: any) => player.username === username)) {
        playerList.push({ username, coords: { x: 0, y: 0 } });
    }

    console.log('User connected:', username);

    socket.join('room');
    socket.emit('message', 'Welcome to the room!');
    socket.emit('playerList', playerList);

    socket.on('joinRoom', (room) => {
        socket.join(room);
        socket.to(room).emit('message', `${username} has joined the room.`);
        socket.to(room).emit('playerList', playerList);
    });

    socket.on('leaveRoom', (room) => {
        socket.leave(room);
        socket.to(room).emit('message', `${username} has left the room.`);
    });

    socket.on('player_moved', (coords) => {
        socket.to('room').emit('player_moved', { username, coords });
    });
})

io.on('disconnect', () => {
    console.log('Socket disconnected');
});

const PORT = process.env.PORT || 3000;
server.listen(PORT, () => console.log(`Server running on port ${PORT}`));