import express from 'express';
// bcryptjs is a pure-JS drop-in (same hash/compare API, same output format)
// — switching from native `bcrypt` here eliminated one C++ compile from
// the install path. Existing $2a$/$2b$ hashes in the DB remain valid;
// bcryptjs recognizes both prefixes so logins work across the swap.
import bcrypt from 'bcryptjs';
import { userDb, db } from '../database/db.js';
import { generateToken, authenticateToken } from '../middleware/auth.js';
import { getPublicRemoteConnectionConfig, saveRemoteConnectionConfig, } from '../services/remote-connection.js';
const router = express.Router();
// Check auth status and setup requirements
router.get('/status', async (req, res) => {
    try {
        const hasUsers = await userDb.hasUsers();
        res.json({
            needsSetup: !hasUsers,
            isAuthenticated: false // Will be overridden by frontend if token exists
        });
    }
    catch (error) {
        console.error('Auth status error:', error);
        res.status(500).json({ error: 'Internal server error' });
    }
});
// First-run connection mode is intentionally public: it is needed before
// account creation so a fresh desktop install can decide whether it controls
// this machine or a remote Pixcode server.
router.get('/connection-mode', (req, res) => {
    res.json({ success: true, connection: getPublicRemoteConnectionConfig() });
});
router.put('/connection-mode', (req, res) => {
    try {
        res.json({ success: true, connection: saveRemoteConnectionConfig(req.body || {}) });
    }
    catch (error) {
        res.status(400).json({ success: false, error: error.message });
    }
});
// User registration (setup) - only allowed if no users exist
router.post('/register', async (req, res) => {
    try {
        const { username, password } = req.body;
        // Validate input
        if (!username || !password) {
            return res.status(400).json({ error: 'Username and password are required' });
        }
        if (username.length < 3 || password.length < 6) {
            return res.status(400).json({ error: 'Username must be at least 3 characters, password at least 6 characters' });
        }
        // Use a transaction to prevent race conditions
        db.prepare('BEGIN').run();
        try {
            // Check if users already exist (only allow one user)
            const hasUsers = userDb.hasUsers();
            if (hasUsers) {
                db.prepare('ROLLBACK').run();
                return res.status(403).json({ error: 'User already exists. This is a single-user system.' });
            }
            // Hash password
            const saltRounds = 12;
            const passwordHash = await bcrypt.hash(password, saltRounds);
            // Create user
            const user = userDb.createUser(username, passwordHash);
            // Generate token
            const token = generateToken(user);
            db.prepare('COMMIT').run();
            // Update last login (non-fatal, outside transaction)
            userDb.updateLastLogin(user.id);
            res.json({
                success: true,
                user: { id: user.id, username: user.username },
                token
            });
        }
        catch (error) {
            db.prepare('ROLLBACK').run();
            throw error;
        }
    }
    catch (error) {
        console.error('Registration error:', error);
        if (error.code === 'SQLITE_CONSTRAINT_UNIQUE') {
            res.status(409).json({ error: 'Username already exists' });
        }
        else {
            res.status(500).json({ error: 'Internal server error' });
        }
    }
});
// User login
router.post('/login', async (req, res) => {
    try {
        const { username, password } = req.body;
        // Validate input
        if (!username || !password) {
            return res.status(400).json({ error: 'Username and password are required' });
        }
        // Get user from database
        const user = userDb.getUserByUsername(username);
        if (!user) {
            return res.status(401).json({ error: 'Invalid username or password' });
        }
        // Verify password
        const isValidPassword = await bcrypt.compare(password, user.password_hash);
        if (!isValidPassword) {
            return res.status(401).json({ error: 'Invalid username or password' });
        }
        // Generate token
        const token = generateToken(user);
        // Update last login
        userDb.updateLastLogin(user.id);
        res.json({
            success: true,
            user: { id: user.id, username: user.username },
            token
        });
    }
    catch (error) {
        console.error('Login error:', error);
        res.status(500).json({ error: 'Internal server error' });
    }
});
// Get current user (protected route)
router.get('/user', authenticateToken, (req, res) => {
    res.json({
        user: req.user
    });
});
// Logout (client-side token removal, but this endpoint can be used for logging)
router.post('/logout', authenticateToken, (req, res) => {
    // In a simple JWT system, logout is mainly client-side
    // This endpoint exists for consistency and potential future logging
    res.json({ success: true, message: 'Logged out successfully' });
});
export default router;
//# sourceMappingURL=auth.js.map