const express = require('express');
const router = express.Router();
const bcrypt = require('bcrypt');
const crypto = require('crypto');
const auth = require('../middleware/auth');
const AuthService = require('../services/AuthService');
const EmailService = require('../services/EmailService');
const db = require('../config/database'); // Direct DB access for quick token update might be needed if not in AuthService

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

    if (!codigo || !password) {
        return res.status(400).json({ error: 'Codigo y password son requeridos' });
    }

    try {
        const tableCheck = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='Usuarios'").get();
        if (!tableCheck) {
            return res.status(500).json({ error: 'Base de datos no inicializada. Ejecuta las migraciones.' });
        }

        const result = await AuthService.login({
            codigo,
            password,
            ip: req.ip,
            userAgent: req.get('user-agent'),
        });

        if (!result) {
            return res.status(401).json({ error: 'Credenciales invalidas' });
        }

        return res.json(result);
    } catch (error) {
        console.error('Login error:', error);
        const detail = process.env.NODE_ENV === 'development' ? error.message : undefined;
        return res.status(500).json({ error: 'Error al iniciar sesion', detail });
    }
});

router.post('/logout', auth, (req, res) => {
    try {
        AuthService.revokeSession(req.token);
        AuthService.logAudit({
            usuarioId: req.user.UsuarioID,
            accion: 'LOGOUT',
            entidad: 'Usuarios',
            entidadId: req.user.UsuarioID,
            ip: req.ip,
        });
        return res.json({ message: 'Sesion cerrada' });
    } catch (error) {
        return res.status(500).json({ error: 'Error al cerrar sesion' });
    }
});

router.get('/me', auth, (req, res) => {
    return res.json({ user: req.user });
});

router.post('/cambiar-password', auth, async (req, res) => {
    const { currentPassword, newPassword } = req.body;

    if (!currentPassword || !newPassword) {
        return res.status(400).json({ error: 'Password actual y nuevo requeridos' });
    }

    try {
        const user = AuthService.getUserById(req.user.UsuarioID);
        const isValid = await bcrypt.compare(currentPassword, user.Password);
        if (!isValid) {
            return res.status(401).json({ error: 'Password actual incorrecto' });
        }

        await AuthService.updatePassword(req.user.UsuarioID, newPassword);
        AuthService.logAudit({
            usuarioId: req.user.UsuarioID,
            accion: 'CAMBIAR_PASSWORD',
            entidad: 'Usuarios',
            entidadId: req.user.UsuarioID,
            ip: req.ip,
        });

        return res.json({ message: 'Password actualizado' });
    } catch (error) {
        return res.status(500).json({ error: 'Error al cambiar password' });
    }
});

router.post('/forgot-password', async (req, res) => {
    const { email } = req.body;
    if (!email) return res.status(400).json({ error: 'Email requerido' });

    try {
        // Find user by Email
        const stmt = db.prepare('SELECT UsuarioID, Nombre FROM Usuarios WHERE Email = ?');
        const user = stmt.get(email);

        if (!user) {
            // Return success even if not found to prevent enumeration
            return res.json({ message: 'Si el email existe, se enviará un enlace.' });
        }

        // Generate Token
        const token = crypto.randomBytes(32).toString('hex');
        const expiry = new Date(Date.now() + 3600000).toISOString(); // 1 hour

        // Save Token
        const updateStmt = db.prepare('UPDATE Usuarios SET ResetToken = ?, ResetTokenExpiry = ? WHERE UsuarioID = ?');
        updateStmt.run(token, expiry, user.UsuarioID);

        // Send Email
        // Assuming frontend is running on 5173 or configured via ENV
        const frontendUrl = process.env.FRONTEND_URL || 'http://localhost:5173';
        const resetLink = `${frontendUrl}/reset-password?token=${token}`;

        await EmailService.sendPasswordReset(email, resetLink);

        return res.json({ message: 'Enlace enviado (Revisa tu consola backend por ahora)' });
    } catch (error) {
        console.error(error);
        return res.status(500).json({ error: 'Error procesando solicitud' });
    }
});

router.post('/reset-password', async (req, res) => {
    const { token, newPassword } = req.body;

    if (!token || !newPassword) {
        return res.status(400).json({ error: 'Token y nuevo password requeridos' });
    }

    try {
        // Find user with valid token
        const stmt = db.prepare('SELECT UsuarioID FROM Usuarios WHERE ResetToken = ? AND ResetTokenExpiry > ?');
        const user = stmt.get(token, new Date().toISOString());

        if (!user) {
            return res.status(400).json({ error: 'Token inválido o expirado' });
        }

        // Update Password and Clear Token
        // Reuse AuthService logic ideally, but direct for now
        const hashedPassword = await bcrypt.hash(newPassword, 10);
        const updateStmt = db.prepare('UPDATE Usuarios SET Password = ?, ResetToken = NULL, ResetTokenExpiry = NULL WHERE UsuarioID = ?');
        updateStmt.run(hashedPassword, user.UsuarioID);

        return res.json({ message: 'Contraseña restablecida correctamente. Ya puedes iniciar sesión.' });
    } catch (error) {
        console.error(error);
        return res.status(500).json({ error: 'Error restableciendo contraseña' });
    }
});

module.exports = router;
