// Task Team — Invitation System — 2026-03-30
const crypto = require('crypto');

async function invitationRoutes(app) {

    // Create invitation
    app.post('/invitations', async (req) => {
        const { task_id, invitee_email, invitee_name, message, inviter_id } = req.body;
        if (!task_id) throw { statusCode: 400, message: 'task_id is required' };

        const token = crypto.randomBytes(32).toString('hex');

        const { rows } = await app.db.query(
            `INSERT INTO invitations (token, task_id, inviter_id, invitee_email, invitee_name, message)
             VALUES ($1, $2, $3, $4, $5, $6) RETURNING *`,
            [token, task_id, inviter_id || null, invitee_email || null, invitee_name || '', message || '']
        );

        const invite = rows[0];
        const link = `https://tasks.hasdo.info/invite/${token}`;

        // Generate share links
        const taskRes = await app.db.query('SELECT title FROM tasks WHERE id=$1', [task_id]);
        const taskTitle = taskRes.rows[0]?.title || 'Task';

        let inviterName = 'Someone';
        if (inviter_id) {
            const inviterRes = await app.db.query('SELECT name FROM users WHERE id=$1', [inviter_id]);
            inviterName = inviterRes.rows[0]?.name || 'Someone';
        }

        const shareText = `${inviterName} te pozval do Task Team!\n${taskTitle}\n\n${link}`;
        const shareLinks = {
            whatsapp: `https://wa.me/?text=${encodeURIComponent(shareText)}`,
            telegram: `https://t.me/share/url?url=${encodeURIComponent(link)}&text=${encodeURIComponent(`${inviterName} te pozval: ${taskTitle}`)}`,
            sms: `sms:${invitee_email || ''}?body=${encodeURIComponent(shareText)}`,
            copy: link
        };

        return { data: { invitation: invite, link, share: shareLinks } };
    });

    // Get invitation by token (public - no auth needed)
    app.get('/invite/:token', async (req) => {
        const { rows } = await app.db.query(
            `SELECT i.*, t.title as task_title, t.description as task_description, t.due_at,
                    u.name as inviter_name, u.avatar_url as inviter_avatar
             FROM invitations i
             LEFT JOIN tasks t ON i.task_id = t.id
             LEFT JOIN users u ON i.inviter_id = u.id
             WHERE i.token = $1`,
            [req.params.token]
        );
        if (!rows.length) throw { statusCode: 404, message: 'Invitation not found' };

        const invite = rows[0];
        if (invite.status !== 'pending') throw { statusCode: 410, message: 'Invitation already used' };
        if (new Date(invite.expires_at) < new Date()) throw { statusCode: 410, message: 'Invitation expired' };

        return { data: invite };
    });

    // Accept invitation (registers + assigns to task)
    app.post('/invite/:token/accept', async (req) => {
        const { name, password, email } = req.body;

        // Get invitation
        const { rows: invites } = await app.db.query('SELECT * FROM invitations WHERE token=$1', [req.params.token]);
        if (!invites.length) throw { statusCode: 404, message: 'Invitation not found' };
        const invite = invites[0];
        if (invite.status !== 'pending') throw { statusCode: 410, message: 'Already accepted' };
        if (new Date(invite.expires_at) < new Date()) throw { statusCode: 410, message: 'Invitation expired' };

        const userEmail = email || invite.invitee_email;
        if (!userEmail) throw { statusCode: 400, message: 'Email is required' };

        // Find or create user
        let { rows: users } = await app.db.query('SELECT * FROM users WHERE email=$1', [userEmail]);
        let userId;

        if (users.length) {
            userId = users[0].id;
        } else {
            // Register new user
            const bcrypt = require('bcryptjs');
            const hash = password ? await bcrypt.hash(password, 12) : null;
            const settings = hash ? { password_hash: hash } : {};
            const { rows: newUser } = await app.db.query(
                'INSERT INTO users (email, name, auth_provider, settings) VALUES ($1, $2, $3, $4) RETURNING id, email, name',
                [userEmail, name || invite.invitee_name || 'New User', 'email', JSON.stringify(settings)]
            );
            userId = newUser[0].id;
        }

        // Assign to task (avoid duplicates)
        await app.db.query(
            `UPDATE tasks SET assigned_to = array_append(COALESCE(assigned_to, ARRAY[]::uuid[]), $1::uuid)
             WHERE id = $2 AND NOT ($1::uuid = ANY(COALESCE(assigned_to, ARRAY[]::uuid[])))`,
            [userId, invite.task_id]
        );

        // Mark invitation accepted
        await app.db.query(
            "UPDATE invitations SET status='accepted', accepted_at=NOW() WHERE id=$1",
            [invite.id]
        );

        // Generate JWT
        const token = app.jwt.sign({ id: userId, email: userEmail }, { expiresIn: '7d' });

        return {
            data: {
                user: { id: userId, email: userEmail, name: name || invite.invitee_name },
                token,
                task_id: invite.task_id
            }
        };
    });

    // List invitations for a task
    app.get('/tasks/:taskId/invitations', async (req) => {
        const { rows } = await app.db.query(
            'SELECT * FROM invitations WHERE task_id=$1 ORDER BY created_at DESC',
            [req.params.taskId]
        );
        return { data: rows };
    });

    // Revoke invitation
    app.delete('/invitations/:id', async (req) => {
        const { rows } = await app.db.query(
            "UPDATE invitations SET status='revoked' WHERE id=$1 AND status='pending' RETURNING *",
            [req.params.id]
        );
        if (!rows.length) throw { statusCode: 404, message: 'Invitation not found or already used' };
        return { data: rows[0] };
    });
}

module.exports = invitationRoutes;
