import bcrypt from "bcrypt";
import jwt from "jsonwebtoken";
import User from "../models/user.model.js";
import { sendResetPasswordMail, sendSignupMail, } from "../utils/mailer.js";
import crypto from "crypto";


export async function signup(req, res) {
  try {
    const { email, password } = req.body;
    if (!email || !password)
      return res.status(400).json({ error: "Email and password required" });

    const exists = await User.findOne({ email });
    if (exists) return res.status(400).json({ error: "User already exists" });

    const passwordHash = await bcrypt.hash(password, 10);
    const user = await User.create({ email, passwordHash });

    // ✅ send confirmation email (non-blocking)
    sendSignupMail(email)
      .then(() => console.log("Signup email sent to", email))
      .catch(err => console.error("Email send failed:", err));

    res.status(201).json({ message: "Signup success, email sent", id: user._id });
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: "Signup failed" });
  }
}

export async function login(req, res) {
  try {
    const { email, password } = req.body;
    const user = await User.findOne({ email });
    if (!user) return res.status(401).json({ error: "Invalid credentials" });

    const match = await bcrypt.compare(password, user.passwordHash);
    if (!match) return res.status(401).json({ error: "Invalid credentials" });

    const token = jwt.sign(
      { id: user._id, email: user.email },
      process.env.JWT_SECRET,
      { expiresIn: "1h" }
    );

    res.json({ message: "Login success", token });
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: "Login failed" });
  }
}

/**
 * POST /api/auth/change-password
 * Body: { currentPassword, newPassword }
 * Header: Authorization: Bearer <token>
 */
export async function changePassword(req, res) {
  try {
    const { currentPassword, newPassword } = req.body;

    // if using FormData, fields come from req.body AFTER a multipart parser
    if (!currentPassword || !newPassword) {
      return res.status(400).json({ error: "Current password and new password are required" });
    }

    const user = await User.findById(req.user.id);
    if (!user) return res.status(404).json({ error: "User not found" });

    const isMatch = await bcrypt.compare(currentPassword, user.passwordHash);
    if (!isMatch)
      return res.status(401).json({ error: "Current password is incorrect" });

    user.passwordHash = await bcrypt.hash(newPassword, 10);
    await user.save();

    res.json({ message: "Password updated successfully" });
  } catch (err) {
    console.error("changePassword error:", err);   // ✅ show actual error
    res.status(500).json({ error: "Failed to change password" });
  }
}

/**
 * POST /api/auth/forgot-password
 * Body: { email }
 */
export async function forgotPassword(req, res) {
  try {
    const { email } = req.body;
    if (!email) return res.status(400).json({ error: "Email is required" });

    const user = await User.findOne({ email });

    if (!user)
      return res.json({
        message: "If the email is registered, a reset link has been sent.",
        verificationCode: null,  // user not found
      });

    // Generate 4-digit numeric verification code
    const verificationCode = Math.floor(1000 + Math.random() * 9000).toString();

    // Save code and expiry in DB
    user.resetPasswordToken = verificationCode;
    user.resetPasswordExpires = Date.now() + 60 * 60 * 1000; // 1 hour
    await user.save();

    // Send code via email
    await sendResetPasswordMail(email, verificationCode);

    // ✅ Return verification code in response
    res.json({
      message: "If the email is registered, a reset link has been sent.",
      verificationCode,  // This is the 4-digit code
    });
  } catch (err) {
    console.error("forgotPassword error:", err);
    res.status(500).json({ error: "Failed to send reset link" });
  }
}

/**
 * POST /api/auth/reset-password
 * Body: { token, newPassword }
 */
export async function resetPassword(req, res) {
  try {
    const { token, newPassword } = req.body;
    if (!token || !newPassword)
      return res.status(400).json({ error: "Token and new password are required" });

    const user = await User.findOne({
      resetPasswordToken: token,
      resetPasswordExpires: { $gt: Date.now() },
    });
    if (!user) return res.status(400).json({ error: "Invalid or expired token" });

    user.passwordHash = await bcrypt.hash(newPassword, 10);
    user.resetPasswordToken = undefined;
    user.resetPasswordExpires = undefined;
    await user.save();

    res.json({ message: "Password has been reset successfully" });
  } catch (err) {
    console.error("resetPassword error:", err);
    res.status(500).json({ error: "Failed to reset password" });
  }
}