const router = require('express').Router();
const auth = require('../core/auth.core');
const jwt = require('../tools/jwt');

const CONSOLE_URL = process.env.CONSOLE_URL || 'http://localhost:3004';
const COOKIE_DOMAIN = process.env.COOKIE_DOMAIN || undefined;

const USERNAME_REGEX = /^[a-zA-Z0-9_.\-]{3,50}$/;
const PASSWORD_MIN_LENGTH = 8;
const PASSWORD_MAX_LENGTH = 128;

const ERROR_RESPONSES = {
    csrf: { success: false, error: 'csrf', message: 'Richiesta non valida, riprova' },
    invalid_credentials: { success: false, error: 'invalid_credentials', message: 'Credenziali non valide' },
    internal: { success: false, error: 'internal', message: 'Errore interno, riprova più tardi' }
};

/**
 * Restituisce un redirect sicuro, scartando URL che puntano ad API
 * o ad host diversi da CONSOLE_URL.
 */
function resolveSafeRedirect(redirect) {
    if (!redirect || typeof redirect !== 'string') return CONSOLE_URL;

    try {
        const redirectUrl = new URL(redirect);
        const consoleUrl = new URL(CONSOLE_URL);

        const sameHost = redirectUrl.hostname === consoleUrl.hostname;
        const notApi = !redirectUrl.pathname.startsWith('/api/');

        if (sameHost && notApi) return redirect;
    } catch {
        // URL non valido / relativo: fallback a CONSOLE_URL
    }

    return CONSOLE_URL;
}

router.post('/register', async (req, res) => {
    const { username, password } = req.body;

    if (!username || !password || typeof username !== 'string' || typeof password !== 'string') {
        return res.status(400).json({ success: false, error: 'Username e password richiesti' });
    }

    if (!USERNAME_REGEX.test(username)) {
        return res.status(400).json({
            success: false,
            error: 'Username non valido. 3-50 caratteri alfanumerici, underscore, punto o trattino.'
        });
    }

    if (password.length < PASSWORD_MIN_LENGTH || password.length > PASSWORD_MAX_LENGTH) {
        return res.status(400).json({
            success: false,
            error: `Password deve essere tra ${PASSWORD_MIN_LENGTH} e ${PASSWORD_MAX_LENGTH} caratteri`
        });
    }

    try {
        await auth.register(username, password);
        return res.status(201).json({ success: true });
    } catch (err) {
        if (err.message === 'User already exists') {
            return res.status(409).json({ success: false, error: 'User already exists' });
        }
        console.error('[AUTH] Register failed:', err.message);
        return res.status(500).json({ success: false, error: 'Errore interno' });
    }
});

router.post('/login', async (req, res) => {
    const { username, password, redirect, _csrf } = req.body;

    const csrfCookie = req.cookies && req.cookies._csrf;
    if (!_csrf || !csrfCookie || _csrf !== csrfCookie) {
        return res.status(400).json(ERROR_RESPONSES.csrf);
    }

    if (!username || !password || typeof username !== 'string' || typeof password !== 'string') {
        return res.status(400).json(ERROR_RESPONSES.invalid_credentials);
    }

    if (username.length > 50 || password.length > PASSWORD_MAX_LENGTH) {
        return res.status(400).json(ERROR_RESPONSES.invalid_credentials);
    }

    const safeRedirect = resolveSafeRedirect(redirect);

    try {
        const user = await auth.login(username, password);
        const session = await auth.newSession(user.id, req.headers['user-agent'], req.ip);
        const token = jwt.generateToken(user, session.id);

        const cookieOptions = {
            httpOnly: true,
            secure: process.env.NODE_ENV === 'production',
            sameSite: 'lax',
            maxAge: 7 * 24 * 60 * 60 * 1000
        };
        if (COOKIE_DOMAIN) cookieOptions.domain = COOKIE_DOMAIN;

        res.cookie('auth_token', token, cookieOptions);
        res.clearCookie('_csrf');

        return res.status(200).json({
            success: true,
            redirect_url: safeRedirect,
            message: 'Login effettuato con successo'
        });
    } catch (err) {
        if (err.message === 'No user matched' || err.message === 'Password mismatch') {
            return res.status(401).json(ERROR_RESPONSES.invalid_credentials);
        }
        if (err.message === 'User account is not active') {
            return res.status(403).json({
                success: false,
                error: 'account_inactive',
                message: 'Account disattivato'
            });
        }
        console.error('[AUTH] Login error:', err.message);
        return res.status(500).json(ERROR_RESPONSES.internal);
    }
});

router.post('/logout', async (req, res) => {
    const token = req.cookies && req.cookies.auth_token;

    if (token) {
        try {
            const verified = jwt.verifyToken(token);
            if (verified.valid) {
                await auth.logout(verified.payload.session_id);
            }
        } catch (err) {
            console.error('[AUTH] Logout error:', err.message);
        }
    }

    const clearOptions = { httpOnly: true, sameSite: 'lax' };
    if (COOKIE_DOMAIN) clearOptions.domain = COOKIE_DOMAIN;

    res.clearCookie('auth_token', clearOptions);
    return res.status(200).json({ success: true, redirect_url: '/login' });
});

module.exports = router;
