const db = require('../config/db');
const {sendVerificationEmail, sendResetEmail} = require('../utils/sendEmail');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const nodemailer = require('nodemailer');
const crypto = require('crypto');

const transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
        user: process.env.EMAIL_USER,
        pass: process.env.EMAIL_PASS
    }
});

exports.registerUser = async (req, res) => {
    try {
        const {username, email, password} = req.body;

        // Verifica si ya existe un usuario con ese username o email
        const [existing] = await db.execute(
            'SELECT * FROM users WHERE username = ? OR email = ?',
            [username, email]
        );

        if (existing.length > 0) {
            return res.status(400).json({success: false, message: "Usuario ya registrado."});
        }

        const hashedPassword = await bcrypt.hash(password, 10);
        const token = crypto.randomBytes(32).toString('hex');

        // Inserta el nuevo usuario con el token
        await db.execute(
            'INSERT INTO users (username, email, password, is_verified, verificationToken) VALUES (?, ?, ?, 0, ?)',
            [username, email, hashedPassword, token]
        );

        await sendVerificationEmail(email, token);

        res.status(201).json({success: true, message: "Usuario registrado. Verifica tu correo."});

    } catch (err) {
        console.error("❌ Error en registerUser:", err);
        res.status(500).json({success: false, message: "Error en el servidor."});
    }
};


exports.verifyEmail = async (req, res) => {
    const token = req.params.token;
    try {
        const [rows] = await db.execute(
            'SELECT * FROM users WHERE verificationToken = ?',
            [token]
        );

        if (rows.length === 0) {
            return res.redirect('/verify-failed.html');
        }

        await db.execute(
            'UPDATE users SET is_verified = 1, verificationToken = NULL WHERE verificationToken = ?',
            [token]
        );

        return res.redirect('/verify-success.html');

    } catch (err) {
        console.error("❌ Error en verifyEmail:", err);
        return res.redirect('/verify-failed.html');
    }
};


exports.loginUser = async (req, res) => {
    const {username, password} = req.body;
    if (!username || !password) {
        return res.status(400).json({success: false, message: 'Usuario y contraseña requeridos'});
    }

    try {
        const [results] = await db.execute('SELECT * FROM users WHERE username = ? LIMIT 1', [username]);
        if (results.length === 0) {
            return res.status(401).json({success: false, message: 'Usuario no encontrado'});
        }

        const user = results[0];
        const passwordMatch = await bcrypt.compare(password, user.password);

        if (!passwordMatch) {
            return res.status(401).json({success: false, message: 'Contraseña incorrecta'});
        }

        if (!user.is_verified) {
            return res.status(403).json({success: false, message: 'Tu correo no ha sido verificado'});
        }

        res.json({
            success: true,
            user: {id: user.id, username: user.username},
            message: 'Inicio de sesión exitoso'
        });
    } catch (err) {
        res.status(500).json({success: false, message: 'Error en el servidor', error: err.message});
    }
};

exports.forgotPassword = async (req, res) => {
    const {email} = req.body;

    try {
        const [users] = await db.execute('SELECT id FROM users WHERE email = ?', [email]);
        if (users.length === 0) return res.status(404).json({message: 'Correo no encontrado'});

        const token = crypto.randomBytes(32).toString('hex');
        await db.execute('INSERT INTO password_resets (user_id, token) VALUES (?, ?)', [users[0].id, token]);

        const resetLink = `http://localhost:3000/reset-password/${token}`;

        // ✔️ Usa la función reutilizable
        await sendResetEmail(email, resetLink);

        res.json({message: 'Correo enviado con instrucciones'});
    } catch (err) {
        console.error('Error al enviar token de recuperación:', err);
        res.status(500).json({message: 'Error interno del servidor'});
    }
};

exports.resetPassword = async (req, res) => {
    const {email, token, newPassword} = req.body;

    if (!email || !token || !newPassword) {
        return res.status(400).json({message: 'Todos los campos son obligatorios.'});
    }

    try {
        const [rows] = await db.execute(
            'SELECT user_id FROM password_resets WHERE token = ?',
            [token]
        );

        if (rows.length === 0) {
            return res.status(400).json({message: 'Token inválido o expirado'});
        }

        const userId = rows[0].user_id;
        const hashedPassword = await bcrypt.hash(newPassword, 10);

        await db.execute(
            'UPDATE users SET password = ? WHERE id = ?',
            [hashedPassword, userId]
        );

        await db.execute(
            'DELETE FROM password_resets WHERE token = ?',
            [token]
        );

        res.json({message: 'Contraseña actualizada correctamente'});

    } catch (err) {
        console.error('❌ Error al restablecer contraseña:', err);
        res.status(500).json({message: 'Error interno del servidor'});
    }
};


exports.getUserStats = async (req, res) => {
    const userId = req.params.id;

    try {
        const [animeStatsRows] = await db.execute(
            'SELECT status, COUNT(*) as count FROM anime WHERE userId = ? GROUP BY status',
            [userId]
        );

        const [mangaStatsRows] = await db.execute(
            'SELECT status, COUNT(*) as count FROM manga WHERE userId = ? GROUP BY status',
            [userId]
        );

        const formatStats = (rows) => {
            const stats = {};
            rows.forEach(row => {
                stats[row.status] = row.count;
            });
            return stats;
        };

        res.json({
            animeStats: animeStatsRows.length ? formatStats(animeStatsRows) : {},
            mangaStats: mangaStatsRows.length ? formatStats(mangaStatsRows) : {}
        });

    } catch (err) {
        res.status(500).json({
            success: false,
            message: 'Error al obtener estadísticas',
            error: err.message
        });
    }
};
