const express = require('express');
const router = express.Router();
const AdminAuthService = require('../services/AdminAuthService');
const { requireAdminAuth } = require('../middlewares/auth');
const { requireCsrf } = require('../middlewares/csrf');

router.get('/setup/status', async (req, res) => {
    /*
        #swagger.tags = ['Admin Authentication']
        #swagger.summary = 'Check onboarding status'
        #swagger.description = 'Returns whether the initial admin setup is still pending and if a session already exists.'
    */
    try {
        const needsSetup = await AdminAuthService.needsInitialSetup();
        const sessionUser = req.session && req.session.user
            ? {
                id: req.session.user.id,
                username: req.session.user.username,
                role: req.session.user.role,
                requiresPasswordChange: Boolean(req.session.user.requiresPasswordChange)
            }
            : null;
        res.json({
            needsSetup,
            hasSession: Boolean(sessionUser),
            user: sessionUser
        });
    } catch (error) {
        console.error('[Auth] setup/status error:', error);
        res.status(500).json({ error: 'SETUP_STATUS_FAILED' });
    }
});

router.post('/setup/initial-admin', async (req, res) => {
    /*
        #swagger.tags = ['Admin Authentication']
        #swagger.summary = 'Complete initial admin setup'
        #swagger.description = 'Creates the very first admin account and immediately starts a session.'
    */
    try {
        const { username, password } = req.body || {};
        if (!username || !password) {
            return res.status(400).json({ error: 'USERNAME_AND_PASSWORD_REQUIRED' });
        }

        const user = await AdminAuthService.createInitialAdmin({ username, password });
        const csrfToken = AdminAuthService.startSession(req, {
            ...user,
            requiresPasswordChange: false
        });

        res.status(201).json({
            success: true,
            user: {
                id: user.id,
                username: user.username,
                role: user.role
            },
            csrfToken
        });
    } catch (error) {
        console.error('[Auth] initial setup error:', error.message);
        switch (error.message) {
            case 'SETUP_ALREADY_COMPLETED':
                return res.status(409).json({ error: 'SETUP_ALREADY_COMPLETED' });
            case 'USERNAME_REQUIRED':
                return res.status(400).json({ error: 'USERNAME_REQUIRED' });
            case 'PASSWORD_TOO_WEAK':
                return res.status(400).json({ error: 'PASSWORD_TOO_WEAK' });
            default:
                if (error.message && error.message.includes('UNIQUE')) {
                    return res.status(409).json({ error: 'USERNAME_IN_USE' });
                }
                return res.status(500).json({ error: 'INITIAL_SETUP_FAILED' });
        }
    }
});

router.post('/login', async (req, res) => {
    /*
        #swagger.tags = ['Admin Authentication']
        #swagger.summary = 'Admin login'
        #swagger.description = 'Starts a server-side admin session and returns a CSRF token.'
    */
    try {
        const { username, password } = req.body || {};
        if (!username || !password) {
            return res.status(400).json({ error: 'USERNAME_AND_PASSWORD_REQUIRED' });
        }

        if (await AdminAuthService.needsInitialSetup()) {
            return res.status(409).json({ error: 'SETUP_REQUIRED' });
        }

        const user = await AdminAuthService.verifyCredentials(username, password);
        if (!user) {
            return res.status(401).json({ error: 'INVALID_CREDENTIALS' });
        }

        const csrfToken = AdminAuthService.startSession(req, user);
        res.json({
            success: true,
            user: {
                id: user.id,
                username: user.username,
                role: user.role,
                requiresPasswordChange: user.requiresPasswordChange
            },
            csrfToken
        });
    } catch (error) {
        console.error('[Auth] login error:', error);
        res.status(500).json({ error: 'LOGIN_FAILED' });
    }
});

router.post('/logout', async (req, res) => {
    /*
        #swagger.tags = ['Admin Authentication']
        #swagger.summary = 'Terminate admin session'
        #swagger.description = 'Destroys the current session and clears the sid cookie.'
    */
    try {
        await AdminAuthService.destroySession(req);
        res.clearCookie('sid');
        res.status(204).send();
    } catch (error) {
        console.error('[Auth] logout error:', error);
        res.status(500).json({ error: 'LOGOUT_FAILED' });
    }
});

router.get('/csrf-token', requireAdminAuth, (req, res) => {
    /*
        #swagger.tags = ['Admin Authentication']
        #swagger.summary = 'Fetch CSRF token'
        #swagger.description = 'Returns a CSRF token for the active admin session (session required).'
    */
    if (!req.session.csrfToken) {
        req.session.csrfToken = AdminAuthService.generateCsrfToken();
    }

    res.json({ csrfToken: req.session.csrfToken });
});

router.post('/change-password', requireAdminAuth, requireCsrf, async (req, res) => {
    /*
        #swagger.tags = ['Admin Authentication']
        #swagger.summary = 'Change admin password'
        #swagger.description = 'Allows a logged-in admin to rotate their password (CSRF protected).'
    */
    try {
        const { currentPassword, newPassword } = req.body || {};
        if (!currentPassword || !newPassword) {
            return res.status(400).json({ error: 'CURRENT_AND_NEW_PASSWORD_REQUIRED' });
        }

        const user = await AdminAuthService.changePassword({
            userId: req.session.user.id,
            currentPassword,
            newPassword
        });

        req.session.user = {
            ...req.session.user,
            requiresPasswordChange: false
        };

        res.json({
            success: true,
            user: {
                id: user.id,
                username: user.username,
                role: user.role,
                requiresPasswordChange: false
            }
        });
    } catch (error) {
        console.error('[Auth] change password error:', error.message || error);
        switch (error.message) {
            case 'CURRENT_PASSWORD_REQUIRED':
                return res.status(400).json({ error: 'CURRENT_PASSWORD_REQUIRED' });
            case 'PASSWORD_TOO_WEAK':
                return res.status(400).json({ error: 'PASSWORD_TOO_WEAK' });
            case 'INVALID_CURRENT_PASSWORD':
                return res.status(400).json({ error: 'INVALID_CURRENT_PASSWORD' });
            case 'USER_NOT_FOUND':
                return res.status(404).json({ error: 'USER_NOT_FOUND' });
            default:
                return res.status(500).json({ error: 'PASSWORD_CHANGE_FAILED' });
        }
    }
});

module.exports = router;
