import dotenv from "dotenv";
import UserModal from "../models/user.js";
import mongoose from 'mongoose';
import bcrypt from "bcryptjs";
import jwt from "jsonwebtoken";
import { sendEmail } from "../utils/sendEmail.js";

dotenv.config();
const secret = process.env.SECRET_KEY;

// This is signup
export const signup = async (req, res) => {
  const { title, email, password, firstName, middleName, lastName, termsconditions, userType, profileImage } = req.body;

  function generateRandomNumber() {
    return Math.floor(Math.random() * 90000) + 10000;
  }

  try {
    // Check if user already exists
    const oldUser = await UserModal.findOne({ email });
    if (oldUser) {
      return res.status(400).json({ message: "User already exists" });
    }

    // Hash the password
    const hashedPassword = await bcrypt.hash(password, 12);
    const randomNumber = generateRandomNumber().toString();
    const userId = `ELUI${randomNumber}`;

    // Create new user
    const result = await UserModal.create({
      title,
      email,
      password: hashedPassword,
      firstName,
      middleName,
      lastName,
      termsconditions,
      userType,
      userId:userId,
      profileImage,
    });

    // Generate JWT (if needed)
    const token = jwt.sign({ email: result.email, id: result._id }, secret, { expiresIn: "7h" });

        // Save the token in the user's tokens array
        result.tokens.push({ token });
        await result.save();

    const url = `Click on the link ${process.env.RETURN_URL}/users/${result._id}/verify/${token}`;
    await sendEmail(result.email, "Verify Email", url);

    // Send the user info and token back to the client
    res.status(201).json({ result, token });

  } catch (error) {
    console.error(error);
    res.status(500).json({ message: "Something went wrong" });
  }
};

//This is to verify user

export const verifyUser = async (req, res) => {
  try {
    const user = await UserModal.findOne({ _id: req.params.id });
    if (!user) return res.status(400).send({ message: "Invalid link" });

    const token = user.tokens.find(
      (tokenObj) => tokenObj.token === req.params.token
    );
    if (!token) return res.status(400).send({ message: "Invalid link" });

    // Update the user's verified status to true
    user.verified = true;
    await user.save();

    // Remove the token from the tokens array
    user.tokens = user.tokens.filter(
      (tokenObj) => tokenObj.token !== req.params.token
    );
    await user.save();

    res.status(200).send({ message: "Email verified successfully" });
  } catch (error) {
    res.status(500).send({ message: "Internal Server Errors" });
  }
};

// This is signIn
export const signin = async (req, res) => {
  const { email, password } = req.body;

  try {
    const oldUser = await UserModal.findOne({ email });
    if (!oldUser)
      return res.status(404).json({ message: "User doesn't exist" });

    const isPasswordCorrect = await bcrypt.compare(password, oldUser.password);

    if (!isPasswordCorrect)
      return res.status(400).json({ message: "Invalid credentials" });

    if (!oldUser.verified) {
      return res.status(401).json({ message: "User is not verified" });
    }

    const token = jwt.sign({ email: oldUser.email, id: oldUser._id }, secret, {
      expiresIn: "8h",
    });

    res.status(200).json({ result: oldUser, token });
  } catch (error) {
    res.status(500).json({ message: "Something went wrong" });
    console.log(error);
  }
};

//To show user

export const showUser = async (req, res) => {
  const { userId } = req.params;

  // Optional: Validate if userId is a MongoDB ObjectId
  if (mongoose.Types.ObjectId.isValid(userId)) {
    try {
      const user = await UserModal.findById(userId);
      if (!user) {
        return res.status(404).json({ message: 'User not found' });
      }
      return res.json(user);
    } catch (error) {
      return res.status(500).json({ message: 'Server Error' });
    }
  } else {
    // If the userId is not an ObjectId, search by other fields (e.g., custom userId)
    try {
      const user = await UserModal.findOne({ userId }); // Adjust based on how your schema stores userId
      if (!user) {
        return res.status(404).json({ message: 'User not found' });
      }
      return res.json(user);
    } catch (error) {
      return res.status(500).json({ message: 'Server Error' });
    }
  }
};



//forgot password

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

  try {
    const user = await UserModal.findOne({ email });
    if (!user) {
      return res.status(404).json({ message: "User not found" });
    }

    const secrets = secret + user.password;
    const token = jwt.sign({ email: user.email, id: user._id }, secrets, {
      expiresIn: "5m",
    });
    user.resetToken = token;
    user.resetTokenExpiration = Date.now() + 300000; // 5 minutes
    await user.save();
    res.status(200).send({ message: "Reset Email alert sent successfully" });

    const url = `CLick on the link ${process.env.RETURN_URL}/users/resetpassword/${user._id}/${token}`;

    await sendEmail(user.email, "Reset Email", url);
    // res.json({ message: 'Password reset successful' });
  } catch (err) {
    console.error("Forgot Password Error:", err);
    res.status(500).json({ message: "Something went wrong" });
  }
};

// To reset password

export const resetPassword = async (req, res) => {
  const { id, token } = req.params;
  const { password } = req.body;

  try {
    if (!password || password.trim() === "") {
      return res.status(400).json({ message: "Password not entered" });
    }

    const user = await UserModal.findOne({ _id: id });
    if (!user) {
      return res.json({ status: "User Not Exists!!" });
    }

    // Update the user's password and clear the reset token
    user.password = await bcrypt.hash(password, 12);
    // user.resetToken = undefined;
    // user.resetTokenExpiration = undefined;
    user.resetToken = token;
    user.resetTokenExpiration = Date.now() + 300000; // 5 minutes

    await user.save();

    res.json({ message: "Password reset successful" });
  } catch (err) {
    console.error("Password Reset Error:", err);
    res.status(500).json({ message: "Something went wrong" });
  }
};


// Update user controller

export const updateUser = async (req, res) => {
  try {
    const { 
      userId, title, firstName, 
      middleName, lastName, email, 
      aboutme, city, state, county, zip, profileImage } = req.body;
    // Use findOneAndUpdate instead, querying by userId (custom field)
    const updatedUser = await UserModal.findOneAndUpdate(
      { userId }, // Query by custom userId, not ObjectId
      { title, firstName, middleName, lastName, email, aboutme, city, state, county, zip, profileImage },
      { new: true } // Return the updated document
    );

    if (!updatedUser) {
      return res.status(404).json({ message: "User not found" });
    }

    res.status(200).json(updatedUser);
  } catch (error) {
    console.error("Error updating user:", error);
    res.status(500).json({ message: "Error updating user", error });
  }
};
