const express = require('express');
const { getConnection, getChannels, getChannel, addChannel, getMessages, getMessage, addMessage, deleteMessage, addMention, getMentions, getUserByUsername, deleMentions } = require('../libs/mysql');
const { checkAuth } = require('../libs/middlewares');

const router = express.Router();

router.get('/', async (req, res) => {
    const connection = await getConnection();
    const channels = await getChannels(connection);
    connection.end();
    res.send(channels);
});

router.get('/:name', async (req, res) => {
    const name = req.params.name;
    const connection = await getConnection();
    const channel = await getChannel(connection, name);
    connection.end();
    if (channel[0]) {
        res.send(channel[0]);
    } else {
        res.send('No channel found');
    }
});

router.get('/:name/messages', async (req, res) => {
    const name = req.params.name;
    const connection = await getConnection();
    const channel = await getChannel(connection, name);
    if (!channel[0]) {
        connection.end();
        return res.send('No channel found');
    }
    const messages = await getMessages(connection, channel[0].id);

    for (const message of messages) {
        if (message.content.includes('@')) {
            const mentions = await getMentions(connection, message.id);
            message.mentions = mentions;
        } else {
            message.mentions = [];
        }
    }
    
    connection.end();
    res.send(messages);
});

router.use('/:name/messages/send', checkAuth);
router.post('/:name/messages/send', async (req, res) => {
    const { message } = req.body;
    const name = req.params.name;
    const user = req.user;

    if (!message) {
        return res.status(400).send({ error: 'Missing parameters' });
    }

    const connection = await getConnection();

    const channel = await getChannel(connection, name);
    if (!channel[0]) {
        connection.end();
        return res.send('No channel found');
    }

    const sent_message = await addMessage(connection, channel[0].id, user.id, message.replace("\"", "'"));
    const message_id = sent_message.insertId;

    for (const word of message.split(' ')) {
        if (word.startsWith('@')) {
            const username = word.substring(1);
            const mentionedUser = await getUserByUsername(connection, username);
            if (mentionedUser[0]) {
                await addMention(connection, message_id, mentionedUser[0].id);
            }
        }
    }

    connection.end();

    req.sockets.emit({
        type: 'new_message',
        channel_id: channel[0].id,
        user_id: user.id,
    });

    res.send({ message: 'Message sent' });
});

router.use('/:name/messages/delete', checkAuth);
router.post('/:name/messages/delete', async (req, res) => {
    const { message_id } = req.body;
    const name = req.params.name;
    const user = req.user;

    if (!message_id) {
        return res.status(400).send({ error: 'Missing message_id' });
    }

    const connection = await getConnection();

    const message = await getMessage(connection, message_id);
    if (!message[0]) {
        connection.end();
        return res.status(400).send({ error: 'No message found' });
    }

    const channel = await getChannel(connection, name);
    if (!channel[0]) {
        connection.end();
        return res.status(400).send({ error: 'No channel found' });
    }

    if (user.id !== channel[0].owner_id && user.id !== message[0].user_id && user.admin !== 1) {
        connection.end();
        return res.status(401).send({ error: 'Unauthorized' });
    }

    await deleteMessage(connection, message_id);
    await deleMentions(connection, message_id);
    connection.end();

    req.sockets.emit({
        type: 'delete_message',
        channel_id: channel[0].id,
        user_id: user.id,
    });

    res.send({ message: 'Message deleted' });
});

router.use('/add', checkAuth);
router.post('/add', async (req, res) => {
    const { name, description } = req.body;
    const user = req.user;

    if (!name || !description) {
        return res.status(400).send({ error: 'Missing parameters' });
    }

    const connection = await getConnection();

    const channel = await getChannel(connection, name);
    if (channel[0]) {
        connection.end();
        return res.status(400).send({ error: 'Channel already exists' });
    }

    if (!/^[a-zA-Z0-9-_]+$/.test(name)) {
        connection.end();
        return res.status(400).send({ error: 'Invalid channel name' });
    }

    await addChannel(connection, name, description, user.id);
    connection.end();

    req.sockets.emit({
        type: 'new_channel'
    });

    res.send({ message: 'Channel added' });
});

module.exports = router;