import { User } from "../models/user.js";
import bcrypt from "bcryptjs";
import jwt from "jsonwebtoken";
import { sendWelcomeEmail, sendVerificationEmail } from "./emailService.js";
import { sendForgetEmail } from "./forgetEmailService.js";
import crypto from "crypto";
import { verifyRecaptcha } from "./recaptchaService.js";


console.log("Line 6 of authController", process.env.JWT_SECRET);
export const registerUser = async (req, res) => {
  try {
    const { userName, email, password, confirmPassword, recaptchaToken } = req.body;

    // Verify reCAPTCHA first
    try {
      await verifyRecaptcha(recaptchaToken, 'signup', 0.5);
    } catch (recaptchaError) {
      console.error('❌ reCAPTCHA verification failed:', recaptchaError.message);
      return res.status(400).json({ 
        message: "reCAPTCHA verification failed. Please try again." 
      });
    }

    // validation
    if (!userName || !email || !password || !confirmPassword) {
      return res.status(400).json({ message: "All fields are required" });
    }

    // Check for spaces in username
    if (/\s/.test(userName)) {
      return res.status(400).json({ message: "Username cannot contain spaces" });
    }

    if (password !== confirmPassword) {
      return res.status(400).json({ message: "Passwords do not match" });
    }

    // checking already existing user
    const existingUser = await User.findOne({ email });
    if (existingUser) {
      return res.status(409).json({ message: "Email already registered" });
    }

    // Hash password
    const salt = await bcrypt.genSalt(10);
    const passwordHash = await bcrypt.hash(password, salt);

    // Generate verification token
    const verificationToken = crypto.randomBytes(32).toString("hex");
    const verificationTokenExpire = Date.now() + 24 * 60 * 60 * 1000; // 24 hours

    // saving new user (unverified)
    const newUser = new User({ 
      userName, 
      email, 
      passwordHash,
      isVerified: false,
      verificationToken,
      verificationTokenExpire
    });
    await newUser.save();
    
    // Send verification email instead of welcome email
    try {
      await sendVerificationEmail(email, userName, verificationToken);
      console.log(`✅ User registered. Verification email sent to: ${email}`);
    } catch (emailError) {
      console.error('⚠️ Verification email failed to send:', emailError.message);
      // Don't block registration if email fails
    }
    
    res.status(201).json({ 
      message: "Registration successful! Please check your email to verify your account.",
      requiresVerification: true
    });
  } catch (err) {
    console.error('❌ Registration error:', err);
    res.status(500).json({ message: "Server error" });
  }
};

// Route for Social Login (Google/LinkedIn or other)
export const socialLoginUser = async (req, res) => {
  const { name, email, photoUrl, socialId, provider, socialEmail } = req.body;

  try {
    // Validate required fields
    if (!socialId) {
      return res.status(400).json({ 
        message: 'Social ID is required' 
      });
    }

    if (!email) {
      return res.status(400).json({ 
        message: 'Email is required (even if placeholder)' 
      });
    }

    console.log('📥 Social login request:', { 
      name, 
      email, 
      socialEmail, 
      provider, 
      photoUrl: photoUrl ? 'provided' : 'missing',
      socialId 
    });

    // ✅ Remove spaces from username for social logins
    const sanitizedUsername = name ? name.replace(/\s+/g, '') : 'SocialUser';

    // Check if the user already exists based on socialId first (more reliable)
    let user = await User.findOne({ socialId });

    if (!user) {
      // If not found by socialId, check by email (for linking accounts)
      user = await User.findOne({ email });
      
      if (user && user.socialId && user.socialId !== socialId) {
        // User exists with different social ID
        return res.status(400).json({ 
          message: 'This email is already associated with another account' 
        });
      }
    }

    if (!user) {
      // If the user doesn't exist, create a new one with social login flag
      user = new User({
        email,
        userName: sanitizedUsername,
        photoUrl: photoUrl || "",
        socialId,
        isSocialLogin: true,
        isVerified: true, // Social logins are auto-verified
        socialProvider: provider || null,
        socialEmail: socialEmail || email, // Store actual social email
      });
      await user.save();
      console.log('✅ New social user created:', user._id, 'with username:', sanitizedUsername);
    } else {
      // If the user exists, update social login details
      if (!user.socialId) {
        user.socialId = socialId;
        user.isSocialLogin = true;
        user.isVerified = true; // Mark as verified when linking social login
      }
      user.userName = sanitizedUsername;
      user.photoUrl = photoUrl || user.photoUrl;
      user.socialProvider = provider || user.socialProvider;
      user.socialEmail = socialEmail || email || user.socialEmail;
      await user.save();
      console.log('✅ Existing user updated:', user._id, 'with username:', sanitizedUsername);
    }

    // Create a token for the user with consistent payload
    const token = jwt.sign(
      { 
        userId: user._id, 
        email: user.email, 
        userName: user.userName 
      },
      process.env.JWT_SECRET,
      { expiresIn: "7d" }
    );

    res.status(200).json({ 
      message: "Login successful", 
      token, 
      user: {
        id: user._id,
        userName: user.userName,
        email: user.email,
        socialEmail: user.socialEmail,
        photoUrl: user.photoUrl,
        isSocialLogin: user.isSocialLogin,
        socialProvider: user.socialProvider
      }
    });
  } catch (err) {
    console.error('❌ Social login error:', err);
    
    // Handle duplicate key error
    if (err.code === 11000) {
      return res.status(400).json({ 
        message: 'User with this social account already exists' 
      });
    }
    
    res.status(500).json({ 
      message: "Server error during social login",
      error: err.message 
    });
  }
};

export const loginUser = async (req, res) => {
  console.log("|Enter");
  try {
    console.log("|Enter try");
    const { email, password } = req.body;

    // filed filled or not
    if (!email || !password) {
      return res
        .status(400)
        .json({ message: "Email and password are required" });
    }

    const user = await User.findOne({ email });
    console.log("|Enter user", user);
    if (!user) return res.status(401).json({ message: "Invalid credentials" });

    // Check if user is verified (skip for social logins)
    if (!user.isVerified && !user.isSocialLogin) {
      return res.status(403).json({ 
        message: "Please verify your email before logging in. Check your inbox for the verification link.",
        requiresVerification: true
      });
    }

    // password match
    const isPasswordMatch = await bcrypt.compare(password, user.passwordHash);
    if (!isPasswordMatch)
      return res.status(401).json({ message: "Invalid credentials" });
    // Create a JWT token valid for 7 days. Payload includes userId to ensure tokens differ per user.
    const token = jwt.sign(
      { userId: user._id.toString(), email: user.email, userName: user.userName },
      process.env.JWT_SECRET,
      { expiresIn: "7d" }
    );
    console.log("=== NEW TOKEN GENERATED ===");
    console.log("User:", user.email, "| UserID:", user._id.toString());
    console.log("Token (first 50 chars):", token.substring(0, 50) + "...");
    console.log("Token issued at:", new Date().toISOString());
    console.log("===========================");
    res.json({ message: "Login successful", token });
  } catch (err) {
    res.status(500).json({ message: "Server error", err });
  }
};

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

    // filed filled or not
    if (!email) {
      return res.status(400).json({ message: "Email is required" });
    }

    const user = await User.findOne({ email });
    if (!user) return res.status(401).json({ message: "Invalid credentials" });

    // create Tokken

    const resetToken = crypto.randomBytes(32).toString("hex");
    // saving hashed token to the database
    user.resetPasswordToken = crypto
      .createHash("sha256")
      .update(resetToken)
      .digest("hex");
    user.resetPasswordExpire = Date.now() + 15 * 60 * 1000; // 15 min expiry
    await user.save();

    // not hashed token in the url
    const resetUrl = `https://cssawwwards.com/reset-password/${resetToken}`;
    const message = `You requested a password reset. Please click on the link: \n\n ${resetUrl}`;

    await sendForgetEmail(user.email, "Password Reset Request", message,user.userName);

    res.status(200).json({ message: "Reset link sent to email." });
  } catch (err) {

     res.status(500).json({ message: "Server error", error: err.message });
  }
};

export const resetPassword = async (req, res) => {

 try {
    const resetTokenHashed = crypto.createHash("sha256").update(req.params.token).digest("hex");
    const user = await User.findOne({
      resetPasswordToken: resetTokenHashed,
      resetPasswordExpire: { $gt: Date.now() }
    });

    if (!user) return res.status(400).json({ message: "Invalid or expired token" });

    // Hash new password
    const salt = await bcrypt.genSalt(10);
    user.passwordHash = await bcrypt.hash(req.body.password, salt);

    user.resetPasswordToken = undefined;
    user.resetPasswordExpire = undefined;

    await user.save();

    res.status(200).json({ message: "Password reset successful!" });
  } catch (err) {
    console.error("Reset password error:", err);
    res.status(500).json({ message: "Server error", error: err.message });
  }
};

// Verify Email
export const verifyEmail = async (req, res) => {
  try {
    const { token } = req.params;

    // Find user with valid verification token
    const user = await User.findOne({
      verificationToken: token,
      verificationTokenExpire: { $gt: Date.now() }
    });

    if (!user) {
      return res.status(400).json({ 
        message: "Invalid or expired verification link. Please request a new verification email." 
      });
    }

    // Mark user as verified
    user.isVerified = true;
    user.verificationToken = undefined;
    user.verificationTokenExpire = undefined;
    await user.save();

    // Send welcome email after successful verification
    sendWelcomeEmail(user.email, user.userName).catch(err => {
      console.error('⚠️ Welcome email failed to send:', err.message);
    });

    console.log(`✅ Email verified for user: ${user.email}`);
    
    res.status(200).json({ 
      message: "Email verified successfully! You can now log in.",
      verified: true
    });
  } catch (err) {
    console.error("Email verification error:", err);
    res.status(500).json({ message: "Server error", error: err.message });
  }
};

// Resend Verification Email
export const resendVerification = async (req, res) => {
  try {
    const { email } = req.body;

    if (!email) {
      return res.status(400).json({ message: "Email is required" });
    }

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

    if (user.isVerified) {
      return res.status(400).json({ message: "Email is already verified" });
    }

    // Generate new verification token
    const verificationToken = crypto.randomBytes(32).toString("hex");
    user.verificationToken = verificationToken;
    user.verificationTokenExpire = Date.now() + 24 * 60 * 60 * 1000; // 24 hours
    await user.save();

    // Send verification email
    await sendVerificationEmail(email, user.userName, verificationToken);

    console.log(`✅ Verification email resent to: ${email}`);
    res.status(200).json({ message: "Verification email sent. Please check your inbox." });
  } catch (err) {
    console.error("Resend verification error:", err);
    res.status(500).json({ message: "Server error", error: err.message });
  }
};
