const User = require("../models/User");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");

const SECRET_KEY = process.env.JWT_SECRET || "MY_SECRET_KEY";
const REFRESH_SECRET_KEY = process.env.JWT_REFRESH_SECRET || "MY_REFRESH_SECRET_KEY";
const ACCESS_TOKEN_EXPIRY = "15m"; // 15 minutes
const REFRESH_TOKEN_EXPIRY = "30d"; // 30 days

// Helper to handle errors consistently
const handleError = (res, error, defaultMessage = "Lỗi server") => {
  console.error('Error:', error);
  
  if (error.code === 11000) {
    // Duplicate key error
    const field = Object.keys(error.keyPattern)[0];
    return res.status(400).json({ 
      message: field === 'email' ? "Email đã được sử dụng" : "Số điện thoại đã được sử dụng" 
    });
  }
  
  if (error.name === 'ValidationError') {
    return res.status(400).json({ 
      message: Object.values(error.errors).map(e => e.message).join(', ')
    });
  }
  
  return res.status(500).json({ 
    message: error.message || defaultMessage 
  });
};

// Helper function to check if string is email
const isEmail = (str) => {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(str);
};

exports.register = async (req, res) => {
  try {
    const { email, phone, password, personalInfo } = req.body;

    // Validate input
    if (!email && !phone) {
      return res.status(400).json({ message: "Vui lòng cung cấp email hoặc số điện thoại" });
    }
    if (!password || password.length < 6) {
      return res.status(400).json({ message: "Mật khẩu phải có ít nhất 6 ký tự" });
    }

    // Check if user exists by email
    if (email) {
      const existingUserByEmail = await User.findOne({ email: email.toLowerCase().trim() });
      if (existingUserByEmail) {
        return res.status(400).json({ message: "Email đã được sử dụng" });
      }
    }

    // Check if user exists by phone
    if (phone) {
      const existingUserByPhone = await User.findOne({ phone: phone.trim() });
      if (existingUserByPhone) {
        return res.status(400).json({ message: "Số điện thoại đã được sử dụng" });
      }
    }

    // Hash password
    const hashedPassword = await bcrypt.hash(password, 10);

    // Prepare user data
    const userData = {
      password: hashedPassword,
      status: "active",
      verified: false,
      permissions: [],
      medicalRecords: [],
      members: []
    };

    // Add email if provided
    if (email) {
      userData.email = email.toLowerCase().trim();
    }

    // Add phone if provided
    if (phone) {
      userData.phone = phone.trim();
    }

    // Add personalInfo if provided
    if (personalInfo) {
      userData.personalInfo = personalInfo;
    }

    const newUser = new User(userData);
    await newUser.save();

    // Generate tokens
    const accessToken = jwt.sign({ id: newUser._id }, SECRET_KEY, { expiresIn: ACCESS_TOKEN_EXPIRY });
    const refreshToken = jwt.sign({ id: newUser._id }, REFRESH_SECRET_KEY, { expiresIn: REFRESH_TOKEN_EXPIRY });

    // Save refresh token to user
    newUser.refreshTokens.push({ token: refreshToken });
    await newUser.save();

    res.status(201).json({ 
      message: "Đăng ký thành công",
      accessToken,
      refreshToken,
      user: {
        id: newUser._id,
        email: newUser.email,
        phone: newUser.phone,
        personalInfo: newUser.personalInfo
      }
    });
  } catch (error) {
    if (error.code === 11000) {
      // Duplicate key error
      const field = Object.keys(error.keyPattern)[0];
      return res.status(400).json({ 
        message: field === 'email' ? "Email đã được sử dụng" : "Số điện thoại đã được sử dụng" 
      });
    }
    return handleError(res, error, "Lỗi đăng ký");
  }
};

exports.login = async (req, res) => {
  try {
    const { email, phone, password, identifier } = req.body;

    // Support both old format (identifier) and new format (email/phone)
    let loginValue = identifier || email || phone;
    
    if (!loginValue) {
      return res.status(400).json({ message: "Vui lòng cung cấp email hoặc số điện thoại" });
    }
    if (!password) {
      return res.status(400).json({ message: "Vui lòng nhập mật khẩu" });
    }

    // Normalize login value
    loginValue = loginValue.trim();
    if (isEmail(loginValue)) {
      loginValue = loginValue.toLowerCase();
    }

    // Find user by email or phone
    const user = await User.findOne({
      $or: [
        { email: loginValue },
        { phone: loginValue }
      ]
    });

    if (!user) {
      return res.status(400).json({ message: "Email/số điện thoại hoặc mật khẩu không đúng" });
    }

    // Check if account is active
    if (user.status !== "active") {
      return res.status(403).json({ message: "Tài khoản đã bị khóa hoặc vô hiệu hóa" });
    }

    // Verify password
    const isMatch = await bcrypt.compare(password, user.password);
    if (!isMatch) {
      return res.status(400).json({ message: "Email/số điện thoại hoặc mật khẩu không đúng" });
    }

    // Generate tokens
    const accessToken = jwt.sign({ id: user._id }, SECRET_KEY, { expiresIn: ACCESS_TOKEN_EXPIRY });
    const refreshToken = jwt.sign({ id: user._id }, REFRESH_SECRET_KEY, { expiresIn: REFRESH_TOKEN_EXPIRY });

    // Save refresh token to user (limit to 5 refresh tokens)
    if (user.refreshTokens.length >= 5) {
      user.refreshTokens.shift(); // Remove oldest token
    }
    user.refreshTokens.push({ token: refreshToken });
    await user.save();

    res.json({ 
      message: "Đăng nhập thành công",
      accessToken,
      refreshToken,
      user: {
        id: user._id,
        email: user.email,
        phone: user.phone,
        personalInfo: user.personalInfo,
        verified: user.verified
      }
    });
  } catch (error) {
    return handleError(res, error, "Lỗi đăng nhập");
  }
};

exports.refreshToken = async (req, res) => {
  try {
    const { refreshToken } = req.body;

    if (!refreshToken) {
      return res.status(400).json({ message: "Refresh token không được cung cấp" });
    }

    // Verify refresh token
    let decoded;
    try {
      decoded = jwt.verify(refreshToken, REFRESH_SECRET_KEY);
    } catch (error) {
      return res.status(401).json({ message: "Refresh token không hợp lệ hoặc đã hết hạn" });
    }

    // Find user and verify refresh token exists
    const user = await User.findById(decoded.id);
    if (!user) {
      return res.status(401).json({ message: "Người dùng không tồn tại" });
    }

    // Check if refresh token exists in user's refresh tokens
    const tokenExists = user.refreshTokens.some(t => t.token === refreshToken);
    if (!tokenExists) {
      return res.status(401).json({ message: "Refresh token không hợp lệ" });
    }

    // Check if account is active
    if (user.status !== "active") {
      return res.status(403).json({ message: "Tài khoản đã bị khóa" });
    }

    // Generate new access token
    const newAccessToken = jwt.sign({ id: user._id }, SECRET_KEY, { expiresIn: ACCESS_TOKEN_EXPIRY });

    res.json({ 
      accessToken: newAccessToken,
      message: "Làm mới token thành công"
    });
  } catch (error) {
    return handleError(res, error, "Lỗi làm mới token");
  }
};

exports.logout = async (req, res) => {
  try {
    const { refreshToken } = req.body;
    const userId = req.user?._id || req.body.userId;

    if (!userId) {
      return res.status(400).json({ message: "Không có thông tin người dùng" });
    }

    const user = await User.findById(userId);
    if (!user) {
      return res.status(404).json({ message: "Người dùng không tồn tại" });
    }

    // Remove refresh token if provided
    if (refreshToken) {
      user.refreshTokens = user.refreshTokens.filter(t => t.token !== refreshToken);
      await user.save();
    }

    res.json({ message: "Đăng xuất thành công" });
  } catch (error) {
    return handleError(res, error, "Lỗi đăng nhập");
  }
};
